Drizzled Public API Documentation

dict0crea.cc
1 /*****************************************************************************
2 
3 Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
4 
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.
8 
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.
12 
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
16 
17 *****************************************************************************/
18 
19 /**************************************************/
26 #include "dict0crea.h"
27 
28 #ifdef UNIV_NONINL
29 #include "dict0crea.ic"
30 #endif
31 
32 #include "btr0pcur.h"
33 #include "btr0btr.h"
34 #include "page0page.h"
35 #include "mach0data.h"
36 #include "dict0boot.h"
37 #include "dict0dict.h"
38 #include "que0que.h"
39 #include "row0ins.h"
40 #include "row0mysql.h"
41 #include "pars0pars.h"
42 #include "trx0roll.h"
43 #include "usr0sess.h"
44 #include "ut0vec.h"
45 
46 /*****************************************************************/
50 static
51 dtuple_t*
52 dict_create_sys_tables_tuple(
53 /*=========================*/
54  const dict_table_t* table,
55  mem_heap_t* heap)
58 {
59  dict_table_t* sys_tables;
60  dtuple_t* entry;
61  dfield_t* dfield;
62  byte* ptr;
63 
64  ut_ad(table);
65  ut_ad(heap);
66 
67  sys_tables = dict_sys->sys_tables;
68 
69  entry = dtuple_create(heap, 8 + DATA_N_SYS_COLS);
70 
71  dict_table_copy_types(entry, sys_tables);
72 
73  /* 0: NAME -----------------------------*/
74  dfield = dtuple_get_nth_field(entry, 0/*NAME*/);
75 
76  dfield_set_data(dfield, table->name, ut_strlen(table->name));
77  /* 3: ID -------------------------------*/
78  dfield = dtuple_get_nth_field(entry, 1/*ID*/);
79 
80  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
81  mach_write_to_8(ptr, table->id);
82 
83  dfield_set_data(dfield, ptr, 8);
84  /* 4: N_COLS ---------------------------*/
85  dfield = dtuple_get_nth_field(entry, 2/*N_COLS*/);
86 
87 #if DICT_TF_COMPACT != 1
88 #error
89 #endif
90 
91  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
92  mach_write_to_4(ptr, table->n_def
93  | ((table->flags & DICT_TF_COMPACT) << 31));
94  dfield_set_data(dfield, ptr, 4);
95  /* 5: TYPE -----------------------------*/
96  dfield = dtuple_get_nth_field(entry, 3/*TYPE*/);
97 
98  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
99  if (table->flags & (~DICT_TF_COMPACT & ~(~0 << DICT_TF_BITS))) {
100  ut_a(table->flags & DICT_TF_COMPACT);
102  ut_a((table->flags & DICT_TF_ZSSIZE_MASK)
103  <= (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));
106  } else {
108  }
109 
110  dfield_set_data(dfield, ptr, 4);
111  /* 6: MIX_ID (obsolete) ---------------------------*/
112  dfield = dtuple_get_nth_field(entry, 4/*MIX_ID*/);
113 
114  ptr = static_cast<unsigned char *>(mem_heap_zalloc(heap, 8));
115 
116  dfield_set_data(dfield, ptr, 8);
117  /* 7: MIX_LEN (additional flags) --------------------------*/
118 
119  dfield = dtuple_get_nth_field(entry, 5/*MIX_LEN*/);
120 
121  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
122  mach_write_to_4(ptr, table->flags >> DICT_TF2_SHIFT);
123 
124  dfield_set_data(dfield, ptr, 4);
125  /* 8: CLUSTER_NAME ---------------------*/
126  dfield = dtuple_get_nth_field(entry, 6/*CLUSTER_NAME*/);
127  dfield_set_null(dfield); /* not supported */
128 
129  /* 9: SPACE ----------------------------*/
130  dfield = dtuple_get_nth_field(entry, 7/*SPACE*/);
131 
132  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
133  mach_write_to_4(ptr, table->space);
134 
135  dfield_set_data(dfield, ptr, 4);
136  /*----------------------------------*/
137 
138  return(entry);
139 }
140 
141 /*****************************************************************/
145 static
146 dtuple_t*
147 dict_create_sys_columns_tuple(
148 /*==========================*/
149  const dict_table_t* table,
150  ulint i,
151  mem_heap_t* heap)
154 {
155  dict_table_t* sys_columns;
156  dtuple_t* entry;
157  const dict_col_t* column;
158  dfield_t* dfield;
159  byte* ptr;
160  const char* col_name;
161 
162  ut_ad(table);
163  ut_ad(heap);
164 
165  column = dict_table_get_nth_col(table, i);
166 
167  sys_columns = dict_sys->sys_columns;
168 
169  entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
170 
171  dict_table_copy_types(entry, sys_columns);
172 
173  /* 0: TABLE_ID -----------------------*/
174  dfield = dtuple_get_nth_field(entry, 0/*TABLE_ID*/);
175 
176  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
177  mach_write_to_8(ptr, table->id);
178 
179  dfield_set_data(dfield, ptr, 8);
180  /* 1: POS ----------------------------*/
181  dfield = dtuple_get_nth_field(entry, 1/*POS*/);
182 
183  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
184  mach_write_to_4(ptr, i);
185 
186  dfield_set_data(dfield, ptr, 4);
187  /* 4: NAME ---------------------------*/
188  dfield = dtuple_get_nth_field(entry, 2/*NAME*/);
189 
190  col_name = dict_table_get_col_name(table, i);
191  dfield_set_data(dfield, col_name, ut_strlen(col_name));
192  /* 5: MTYPE --------------------------*/
193  dfield = dtuple_get_nth_field(entry, 3/*MTYPE*/);
194 
195  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
196  mach_write_to_4(ptr, column->mtype);
197 
198  dfield_set_data(dfield, ptr, 4);
199  /* 6: PRTYPE -------------------------*/
200  dfield = dtuple_get_nth_field(entry, 4/*PRTYPE*/);
201 
202  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
203  mach_write_to_4(ptr, column->prtype);
204 
205  dfield_set_data(dfield, ptr, 4);
206  /* 7: LEN ----------------------------*/
207  dfield = dtuple_get_nth_field(entry, 5/*LEN*/);
208 
209  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
210  mach_write_to_4(ptr, column->len);
211 
212  dfield_set_data(dfield, ptr, 4);
213  /* 8: PREC ---------------------------*/
214  dfield = dtuple_get_nth_field(entry, 6/*PREC*/);
215 
216  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
217  mach_write_to_4(ptr, 0/* unused */);
218 
219  dfield_set_data(dfield, ptr, 4);
220  /*---------------------------------*/
221 
222  return(entry);
223 }
224 
225 /***************************************************************/
228 static
229 ulint
230 dict_build_table_def_step(
231 /*======================*/
232  que_thr_t* thr,
233  tab_node_t* node)
234 {
235  dict_table_t* table;
236  dtuple_t* row;
237  ulint error;
238  ulint flags;
239  const char* path_or_name;
240  ibool is_path;
241  mtr_t mtr;
242  ulint space = 0;
243  ibool file_per_table;
244 
245  ut_ad(mutex_own(&(dict_sys->mutex)));
246 
247  table = node->table;
248 
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;
257 
258  dict_hdr_get_new_id(&table->id, NULL, NULL);
259 
260  thr_get_trx(thr)->table_id = table->id;
261 
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);
265 
266  if (UNIV_UNLIKELY(space == ULINT_UNDEFINED)) {
267  return(DB_ERROR);
268  }
269 
270  /* We create a new single-table tablespace for the table.
271  We initially let it be 4 pages:
272  - page 0 is the fsp header and an extent descriptor page,
273  - page 1 is an ibuf bitmap page,
274  - page 2 is the first inode page,
275  - page 3 will contain the root of the clustered index of the
276  table we create here. */
277 
278  if (table->dir_path_of_temp_table) {
279  /* We place tables created with CREATE TEMPORARY
280  TABLE in the tmp dir of mysqld server */
281 
282  path_or_name = table->dir_path_of_temp_table;
283  is_path = TRUE;
284  } else {
285  path_or_name = table->name;
286  is_path = FALSE;
287  }
288 
290  ut_ad(!dict_table_zip_size(table)
292 
293  flags = table->flags & ~(~0 << DICT_TF_BITS);
295  space, path_or_name, is_path,
296  flags == DICT_TF_COMPACT ? 0 : flags,
298  table->space = (unsigned int) space;
299 
300  if (error != DB_SUCCESS) {
301 
302  return(error);
303  }
304 
305  mtr_start(&mtr);
306 
308 
309  mtr_commit(&mtr);
310  } else {
311  /* Create in the system tablespace: disallow new features */
312  table->flags &= (~0 << DICT_TF_BITS) | DICT_TF_COMPACT;
313  }
314 
315  row = dict_create_sys_tables_tuple(table, node->heap);
316 
317  ins_node_set_new_row(node->tab_def, row);
318 
319  return(DB_SUCCESS);
320 }
321 
322 /***************************************************************/
325 static
326 ulint
327 dict_build_col_def_step(
328 /*====================*/
329  tab_node_t* node)
330 {
331  dtuple_t* row;
332 
333  row = dict_create_sys_columns_tuple(node->table, node->col_no,
334  node->heap);
335  ins_node_set_new_row(node->col_def, row);
336 
337  return(DB_SUCCESS);
338 }
339 
340 /*****************************************************************/
344 static
345 dtuple_t*
346 dict_create_sys_indexes_tuple(
347 /*==========================*/
348  const dict_index_t* index,
349  mem_heap_t* heap)
352 {
353  dict_table_t* sys_indexes;
354  dict_table_t* table;
355  dtuple_t* entry;
356  dfield_t* dfield;
357  byte* ptr;
358 
359  ut_ad(mutex_own(&(dict_sys->mutex)));
360  ut_ad(index);
361  ut_ad(heap);
362 
363  sys_indexes = dict_sys->sys_indexes;
364 
365  table = dict_table_get_low(index->table_name);
366 
367  entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
368 
369  dict_table_copy_types(entry, sys_indexes);
370 
371  /* 0: TABLE_ID -----------------------*/
372  dfield = dtuple_get_nth_field(entry, 0/*TABLE_ID*/);
373 
374  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
375  mach_write_to_8(ptr, table->id);
376 
377  dfield_set_data(dfield, ptr, 8);
378  /* 1: ID ----------------------------*/
379  dfield = dtuple_get_nth_field(entry, 1/*ID*/);
380 
381  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
382  mach_write_to_8(ptr, index->id);
383 
384  dfield_set_data(dfield, ptr, 8);
385  /* 4: NAME --------------------------*/
386  dfield = dtuple_get_nth_field(entry, 2/*NAME*/);
387 
388  dfield_set_data(dfield, index->name, ut_strlen(index->name));
389  /* 5: N_FIELDS ----------------------*/
390  dfield = dtuple_get_nth_field(entry, 3/*N_FIELDS*/);
391 
392  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
393  mach_write_to_4(ptr, index->n_fields);
394 
395  dfield_set_data(dfield, ptr, 4);
396  /* 6: TYPE --------------------------*/
397  dfield = dtuple_get_nth_field(entry, 4/*TYPE*/);
398 
399  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
400  mach_write_to_4(ptr, index->type);
401 
402  dfield_set_data(dfield, ptr, 4);
403  /* 7: SPACE --------------------------*/
404 
405 #if DICT_SYS_INDEXES_SPACE_NO_FIELD != 7
406 #error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 7"
407 #endif
408 
409  dfield = dtuple_get_nth_field(entry, 5/*SPACE*/);
410 
411  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
412  mach_write_to_4(ptr, index->space);
413 
414  dfield_set_data(dfield, ptr, 4);
415  /* 8: PAGE_NO --------------------------*/
416 
417 #if DICT_SYS_INDEXES_PAGE_NO_FIELD != 8
418 #error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 8"
419 #endif
420 
421  dfield = dtuple_get_nth_field(entry, 6/*PAGE_NO*/);
422 
423  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
425 
426  dfield_set_data(dfield, ptr, 4);
427  /*--------------------------------*/
428 
429  return(entry);
430 }
431 
432 /*****************************************************************/
436 static
437 dtuple_t*
438 dict_create_sys_fields_tuple(
439 /*=========================*/
440  const dict_index_t* index,
441  ulint i,
442  mem_heap_t* heap)
445 {
446  dict_table_t* sys_fields;
447  dtuple_t* entry;
448  dict_field_t* field;
449  dfield_t* dfield;
450  byte* ptr;
451  ibool index_contains_column_prefix_field = FALSE;
452  ulint j;
453 
454  ut_ad(index);
455  ut_ad(heap);
456 
457  for (j = 0; j < index->n_fields; j++) {
458  if (dict_index_get_nth_field(index, j)->prefix_len > 0) {
459  index_contains_column_prefix_field = TRUE;
460  break;
461  }
462  }
463 
464  field = dict_index_get_nth_field(index, i);
465 
466  sys_fields = dict_sys->sys_fields;
467 
468  entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS);
469 
470  dict_table_copy_types(entry, sys_fields);
471 
472  /* 0: INDEX_ID -----------------------*/
473  dfield = dtuple_get_nth_field(entry, 0/*INDEX_ID*/);
474 
475  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
476  mach_write_to_8(ptr, index->id);
477 
478  dfield_set_data(dfield, ptr, 8);
479  /* 1: POS + PREFIX LENGTH ----------------------------*/
480 
481  dfield = dtuple_get_nth_field(entry, 1/*POS*/);
482 
483  ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
484 
485  if (index_contains_column_prefix_field) {
486  /* If there are column prefix fields in the index, then
487  we store the number of the field to the 2 HIGH bytes
488  and the prefix length to the 2 low bytes, */
489 
490  mach_write_to_4(ptr, (i << 16) + field->prefix_len);
491  } else {
492  /* Else we store the number of the field to the 2 LOW bytes.
493  This is to keep the storage format compatible with
494  InnoDB versions < 4.0.14. */
495 
496  mach_write_to_4(ptr, i);
497  }
498 
499  dfield_set_data(dfield, ptr, 4);
500  /* 4: COL_NAME -------------------------*/
501  dfield = dtuple_get_nth_field(entry, 2/*COL_NAME*/);
502 
503  dfield_set_data(dfield, field->name,
504  ut_strlen(field->name));
505  /*---------------------------------*/
506 
507  return(entry);
508 }
509 
510 /*****************************************************************/
514 static
515 dtuple_t*
516 dict_create_search_tuple(
517 /*=====================*/
518  const dtuple_t* tuple,
520  mem_heap_t* heap)
522 {
523  dtuple_t* search_tuple;
524  const dfield_t* field1;
525  dfield_t* field2;
526 
527  ut_ad(tuple && heap);
528 
529  search_tuple = dtuple_create(heap, 2);
530 
531  field1 = dtuple_get_nth_field(tuple, 0);
532  field2 = dtuple_get_nth_field(search_tuple, 0);
533 
534  dfield_copy(field2, field1);
535 
536  field1 = dtuple_get_nth_field(tuple, 1);
537  field2 = dtuple_get_nth_field(search_tuple, 1);
538 
539  dfield_copy(field2, field1);
540 
541  ut_ad(dtuple_validate(search_tuple));
542 
543  return(search_tuple);
544 }
545 
546 /***************************************************************/
549 static
550 ulint
551 dict_build_index_def_step(
552 /*======================*/
553  que_thr_t* thr,
554  ind_node_t* node)
555 {
556  dict_table_t* table;
557  dict_index_t* index;
558  dtuple_t* row;
559  trx_t* trx;
560 
561  ut_ad(mutex_own(&(dict_sys->mutex)));
562 
563  trx = thr_get_trx(thr);
564 
565  index = node->index;
566 
567  table = dict_table_get_low(index->table_name);
568 
569  if (table == NULL) {
570  return(DB_TABLE_NOT_FOUND);
571  }
572 
573  trx->table_id = table->id;
574 
575  node->table = table;
576 
577  ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
578  || dict_index_is_clust(index));
579 
580  dict_hdr_get_new_id(NULL, &index->id, NULL);
581 
582  /* Inherit the space id from the table; we store all indexes of a
583  table in the same tablespace */
584 
585  index->space = table->space;
586  node->page_no = FIL_NULL;
587  row = dict_create_sys_indexes_tuple(index, node->heap);
588  node->ind_row = row;
589 
590  ins_node_set_new_row(node->ind_def, row);
591 
592  /* Note that the index was created by this transaction. */
593  index->trx_id = trx->id;
594 
595  return(DB_SUCCESS);
596 }
597 
598 /***************************************************************/
601 static
602 ulint
603 dict_build_field_def_step(
604 /*======================*/
605  ind_node_t* node)
606 {
607  dict_index_t* index;
608  dtuple_t* row;
609 
610  index = node->index;
611 
612  row = dict_create_sys_fields_tuple(index, node->field_no, node->heap);
613 
614  ins_node_set_new_row(node->field_def, row);
615 
616  return(DB_SUCCESS);
617 }
618 
619 /***************************************************************/
622 static
623 ulint
624 dict_create_index_tree_step(
625 /*========================*/
626  ind_node_t* node)
627 {
628  dict_index_t* index;
629  dict_table_t* sys_indexes;
630  dtuple_t* search_tuple;
631  ulint zip_size;
632  btr_pcur_t pcur;
633  mtr_t mtr;
634 
635  ut_ad(mutex_own(&(dict_sys->mutex)));
636 
637  index = node->index;
638 
639  sys_indexes = dict_sys->sys_indexes;
640 
641  /* Run a mini-transaction in which the index tree is allocated for
642  the index and its root address is written to the index entry in
643  sys_indexes */
644 
645  mtr_start(&mtr);
646 
647  search_tuple = dict_create_search_tuple(node->ind_row, node->heap);
648 
649  btr_pcur_open(UT_LIST_GET_FIRST(sys_indexes->indexes),
650  search_tuple, PAGE_CUR_L, BTR_MODIFY_LEAF,
651  &pcur, &mtr);
652 
653  btr_pcur_move_to_next_user_rec(&pcur, &mtr);
654 
655  zip_size = dict_table_zip_size(index->table);
656 
657  node->page_no = btr_create(index->type, index->space, zip_size,
658  index->id, index, &mtr);
659  /* printf("Created a new index tree in space %lu root page %lu\n",
660  index->space, index->page_no); */
661 
662  page_rec_write_index_page_no(btr_pcur_get_rec(&pcur),
663  DICT_SYS_INDEXES_PAGE_NO_FIELD,
664  node->page_no, &mtr);
665  btr_pcur_close(&pcur);
666  mtr_commit(&mtr);
667 
668  if (node->page_no == FIL_NULL) {
669 
670  return(DB_OUT_OF_FILE_SPACE);
671  }
672 
673  return(DB_SUCCESS);
674 }
675 
676 /*******************************************************************/
678 UNIV_INTERN
679 void
681 /*=================*/
682  rec_t* rec,
684  mtr_t* mtr)
685 {
686  ulint root_page_no;
687  ulint space;
688  ulint zip_size;
689  const byte* ptr;
690  ulint len;
691 
692  ut_ad(mutex_own(&(dict_sys->mutex)));
694  ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
695 
696  ut_ad(len == 4);
697 
698  root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
699 
700  if (root_page_no == FIL_NULL) {
701  /* The tree has already been freed */
702 
703  return;
704  }
705 
706  ptr = rec_get_nth_field_old(rec,
707  DICT_SYS_INDEXES_SPACE_NO_FIELD, &len);
708 
709  ut_ad(len == 4);
710 
711  space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
712  zip_size = fil_space_get_zip_size(space);
713 
714  if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
715  /* It is a single table tablespace and the .ibd file is
716  missing: do nothing */
717 
718  return;
719  }
720 
721  /* We free all the pages but the root page first; this operation
722  may span several mini-transactions */
723 
724  btr_free_but_not_root(space, zip_size, root_page_no);
725 
726  /* Then we free the root page in the same mini-transaction where
727  we write FIL_NULL to the appropriate field in the SYS_INDEXES
728  record: this mini-transaction marks the B-tree totally freed */
729 
730  /* printf("Dropping index tree in space %lu root page %lu\n", space,
731  root_page_no); */
732  btr_free_root(space, zip_size, root_page_no, mtr);
733 
735  DICT_SYS_INDEXES_PAGE_NO_FIELD,
736  FIL_NULL, mtr);
737 }
738 
739 /*******************************************************************/
742 UNIV_INTERN
743 ulint
745 /*=====================*/
746  dict_table_t* table,
747  ulint space,
750  btr_pcur_t* pcur,
754  mtr_t* mtr)
757 {
758  ulint root_page_no;
759  ibool drop = !space;
760  ulint zip_size;
761  ulint type;
762  index_id_t index_id;
763  rec_t* rec;
764  const byte* ptr;
765  ulint len;
766  dict_index_t* index;
767 
768  ut_ad(mutex_own(&(dict_sys->mutex)));
770  rec = btr_pcur_get_rec(pcur);
771  ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len);
772 
773  ut_ad(len == 4);
774 
775  root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
776 
777  if (drop && root_page_no == FIL_NULL) {
778  /* The tree has been freed. */
779 
780  ut_print_timestamp(stderr);
781  fprintf(stderr, " InnoDB: Trying to TRUNCATE"
782  " a missing index of table %s!\n", table->name);
783  drop = FALSE;
784  }
785 
786  ptr = rec_get_nth_field_old(rec,
787  DICT_SYS_INDEXES_SPACE_NO_FIELD, &len);
788 
789  ut_ad(len == 4);
790 
791  if (drop) {
792  space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
793  }
794 
795  zip_size = fil_space_get_zip_size(space);
796 
797  if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
798  /* It is a single table tablespace and the .ibd file is
799  missing: do nothing */
800 
801  ut_print_timestamp(stderr);
802  fprintf(stderr, " InnoDB: Trying to TRUNCATE"
803  " a missing .ibd file of table %s!\n", table->name);
804  return(FIL_NULL);
805  }
806 
807  ptr = rec_get_nth_field_old(rec,
808  DICT_SYS_INDEXES_TYPE_FIELD, &len);
809  ut_ad(len == 4);
810  type = mach_read_from_4(ptr);
811 
812  ptr = rec_get_nth_field_old(rec, 1, &len);
813  ut_ad(len == 8);
814  index_id = mach_read_from_8(ptr);
815 
816  if (!drop) {
817 
818  goto create;
819  }
820 
821  /* We free all the pages but the root page first; this operation
822  may span several mini-transactions */
823 
824  btr_free_but_not_root(space, zip_size, root_page_no);
825 
826  /* Then we free the root page in the same mini-transaction where
827  we create the b-tree and write its new root page number to the
828  appropriate field in the SYS_INDEXES record: this mini-transaction
829  marks the B-tree totally truncated */
830 
831  btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
832 
833  btr_free_root(space, zip_size, root_page_no, mtr);
834 create:
835  /* We will temporarily write FIL_NULL to the PAGE_NO field
836  in SYS_INDEXES, so that the database will not get into an
837  inconsistent state in case it crashes between the mtr_commit()
838  below and the following mtr_commit() call. */
839  page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
840  FIL_NULL, mtr);
841 
842  /* We will need to commit the mini-transaction in order to avoid
843  deadlocks in the btr_create() call, because otherwise we would
844  be freeing and allocating pages in the same mini-transaction. */
845  btr_pcur_store_position(pcur, mtr);
846  mtr_commit(mtr);
847 
848  mtr_start(mtr);
849  btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);
850 
851  /* Find the index corresponding to this SYS_INDEXES record. */
852  for (index = UT_LIST_GET_FIRST(table->indexes);
853  index;
854  index = UT_LIST_GET_NEXT(indexes, index)) {
855  if (index->id == index_id) {
856  root_page_no = btr_create(type, space, zip_size,
857  index_id, index, mtr);
858  index->page = (unsigned int) root_page_no;
859  return(root_page_no);
860  }
861  }
862 
863  ut_print_timestamp(stderr);
864  fprintf(stderr,
865  " InnoDB: Index %llu of table %s is missing\n"
866  "InnoDB: from the data dictionary during TRUNCATE!\n",
867  (ullint) index_id,
868  table->name);
869 
870  return(FIL_NULL);
871 }
872 
873 /*********************************************************************/
876 UNIV_INTERN
877 tab_node_t*
879 /*====================*/
880  dict_table_t* table,
882  mem_heap_t* heap)
883 {
884  tab_node_t* node;
885 
886  node = static_cast<tab_node_t *>(mem_heap_alloc(heap, sizeof(tab_node_t)));
887 
888  node->common.type = QUE_NODE_CREATE_TABLE;
889 
890  node->table = table;
891 
892  node->state = TABLE_BUILD_TABLE_DEF;
893  node->heap = mem_heap_create(256);
894 
895  node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables,
896  heap);
897  node->tab_def->common.parent = node;
898 
899  node->col_def = ins_node_create(INS_DIRECT, dict_sys->sys_columns,
900  heap);
901  node->col_def->common.parent = node;
902 
903  node->commit_node = commit_node_create(heap);
904  node->commit_node->common.parent = node;
905 
906  return(node);
907 }
908 
909 /*********************************************************************/
912 UNIV_INTERN
913 ind_node_t*
915 /*====================*/
916  dict_index_t* index,
918  mem_heap_t* heap)
919 {
920  ind_node_t* node;
921 
922  node = static_cast<ind_node_t *>(mem_heap_alloc(heap, sizeof(ind_node_t)));
923 
924  node->common.type = QUE_NODE_CREATE_INDEX;
925 
926  node->index = index;
927 
928  node->state = INDEX_BUILD_INDEX_DEF;
929  node->page_no = FIL_NULL;
930  node->heap = mem_heap_create(256);
931 
932  node->ind_def = ins_node_create(INS_DIRECT,
933  dict_sys->sys_indexes, heap);
934  node->ind_def->common.parent = node;
935 
936  node->field_def = ins_node_create(INS_DIRECT,
937  dict_sys->sys_fields, heap);
938  node->field_def->common.parent = node;
939 
940  node->commit_node = commit_node_create(heap);
941  node->commit_node->common.parent = node;
942 
943  return(node);
944 }
945 
946 /***********************************************************/
949 UNIV_INTERN
950 que_thr_t*
952 /*===================*/
953  que_thr_t* thr)
954 {
955  tab_node_t* node;
956  ulint err = DB_ERROR;
957  trx_t* trx;
958 
959  ut_ad(thr);
960  ut_ad(mutex_own(&(dict_sys->mutex)));
961 
962  trx = thr_get_trx(thr);
963 
964  node = static_cast<tab_node_t *>(thr->run_node);
965 
966  ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_TABLE);
967 
968  if (thr->prev_node == que_node_get_parent(node)) {
969  node->state = TABLE_BUILD_TABLE_DEF;
970  }
971 
972  if (node->state == TABLE_BUILD_TABLE_DEF) {
973 
974  /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
975 
976  err = dict_build_table_def_step(thr, node);
977 
978  if (err != DB_SUCCESS) {
979 
980  goto function_exit;
981  }
982 
983  node->state = TABLE_BUILD_COL_DEF;
984  node->col_no = 0;
985 
986  thr->run_node = node->tab_def;
987 
988  return(thr);
989  }
990 
991  if (node->state == TABLE_BUILD_COL_DEF) {
992 
993  if (node->col_no < (node->table)->n_def) {
994 
995  err = dict_build_col_def_step(node);
996 
997  if (err != DB_SUCCESS) {
998 
999  goto function_exit;
1000  }
1001 
1002  node->col_no++;
1003 
1004  thr->run_node = node->col_def;
1005 
1006  return(thr);
1007  } else {
1008  node->state = TABLE_COMMIT_WORK;
1009  }
1010  }
1011 
1012  if (node->state == TABLE_COMMIT_WORK) {
1013 
1014  /* Table was correctly defined: do NOT commit the transaction
1015  (CREATE TABLE does NOT do an implicit commit of the current
1016  transaction) */
1017 
1018  node->state = TABLE_ADD_TO_CACHE;
1019 
1020  /* thr->run_node = node->commit_node;
1021 
1022  return(thr); */
1023  }
1024 
1025  if (node->state == TABLE_ADD_TO_CACHE) {
1026 
1027  dict_table_add_to_cache(node->table, node->heap);
1028 
1029  err = DB_SUCCESS;
1030  }
1031 
1032 function_exit:
1033  trx->error_state = err;
1034 
1035  if (err == DB_SUCCESS) {
1036  /* Ok: do nothing */
1037 
1038  } else if (err == DB_LOCK_WAIT) {
1039 
1040  return(NULL);
1041  } else {
1042  /* SQL error detected */
1043 
1044  return(NULL);
1045  }
1046 
1047  thr->run_node = que_node_get_parent(node);
1048 
1049  return(thr);
1050 }
1051 
1052 /***********************************************************/
1056 UNIV_INTERN
1057 que_thr_t*
1059 /*===================*/
1060  que_thr_t* thr)
1061 {
1062  ind_node_t* node;
1063  ulint err = DB_ERROR;
1064  trx_t* trx;
1065 
1066  ut_ad(thr);
1067  ut_ad(mutex_own(&(dict_sys->mutex)));
1068 
1069  trx = thr_get_trx(thr);
1070 
1071  node = static_cast<ind_node_t *>(thr->run_node);
1072 
1073  ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_INDEX);
1074 
1075  if (thr->prev_node == que_node_get_parent(node)) {
1076  node->state = INDEX_BUILD_INDEX_DEF;
1077  }
1078 
1079  if (node->state == INDEX_BUILD_INDEX_DEF) {
1080  /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */
1081  err = dict_build_index_def_step(thr, node);
1082 
1083  if (err != DB_SUCCESS) {
1084 
1085  goto function_exit;
1086  }
1087 
1088  node->state = INDEX_BUILD_FIELD_DEF;
1089  node->field_no = 0;
1090 
1091  thr->run_node = node->ind_def;
1092 
1093  return(thr);
1094  }
1095 
1096  if (node->state == INDEX_BUILD_FIELD_DEF) {
1097 
1098  if (node->field_no < (node->index)->n_fields) {
1099 
1100  err = dict_build_field_def_step(node);
1101 
1102  if (err != DB_SUCCESS) {
1103 
1104  goto function_exit;
1105  }
1106 
1107  node->field_no++;
1108 
1109  thr->run_node = node->field_def;
1110 
1111  return(thr);
1112  } else {
1113  node->state = INDEX_ADD_TO_CACHE;
1114  }
1115  }
1116 
1117  if (node->state == INDEX_ADD_TO_CACHE) {
1118 
1119  index_id_t index_id = node->index->id;
1120 
1122  node->table, node->index, FIL_NULL,
1123  trx_is_strict(trx)
1124  || dict_table_get_format(node->table)
1125  >= DICT_TF_FORMAT_ZIP);
1126 
1127  node->index = dict_index_get_if_in_cache_low(index_id);
1128  ut_a(!node->index == (err != DB_SUCCESS));
1129 
1130  if (err != DB_SUCCESS) {
1131 
1132  goto function_exit;
1133  }
1134 
1135  node->state = INDEX_CREATE_INDEX_TREE;
1136  }
1137 
1138  if (node->state == INDEX_CREATE_INDEX_TREE) {
1139 
1140  err = dict_create_index_tree_step(node);
1141 
1142  if (err != DB_SUCCESS) {
1144  node->index = NULL;
1145 
1146  goto function_exit;
1147  }
1148 
1149  node->index->page = node->page_no;
1150  node->state = INDEX_COMMIT_WORK;
1151  }
1152 
1153  if (node->state == INDEX_COMMIT_WORK) {
1154 
1155  /* Index was correctly defined: do NOT commit the transaction
1156  (CREATE INDEX does NOT currently do an implicit commit of
1157  the current transaction) */
1158 
1159  node->state = INDEX_CREATE_INDEX_TREE;
1160 
1161  /* thr->run_node = node->commit_node;
1162 
1163  return(thr); */
1164  }
1165 
1166 function_exit:
1167  trx->error_state = err;
1168 
1169  if (err == DB_SUCCESS) {
1170  /* Ok: do nothing */
1171 
1172  } else if (err == DB_LOCK_WAIT) {
1173 
1174  return(NULL);
1175  } else {
1176  /* SQL error detected */
1177 
1178  return(NULL);
1179  }
1180 
1181  thr->run_node = que_node_get_parent(node);
1182 
1183  return(thr);
1184 }
1185 
1186 /****************************************************************/
1191 UNIV_INTERN
1192 ulint
1194 /*================================================*/
1195 {
1196  dict_table_t* table1;
1197  dict_table_t* table2;
1198  ulint error;
1199  trx_t* trx;
1200 
1201  mutex_enter(&(dict_sys->mutex));
1202 
1203  table1 = dict_table_get_low("SYS_FOREIGN");
1204  table2 = dict_table_get_low("SYS_FOREIGN_COLS");
1205 
1206  if (table1 && table2
1207  && UT_LIST_GET_LEN(table1->indexes) == 3
1208  && UT_LIST_GET_LEN(table2->indexes) == 1) {
1209 
1210  /* Foreign constraint system tables have already been
1211  created, and they are ok */
1212 
1213  mutex_exit(&(dict_sys->mutex));
1214 
1215  return(DB_SUCCESS);
1216  }
1217 
1218  mutex_exit(&(dict_sys->mutex));
1219 
1220  trx = trx_allocate_for_mysql();
1221 
1222  trx->op_info = "creating foreign key sys tables";
1223 
1224  row_mysql_lock_data_dictionary(trx);
1225 
1226  if (table1) {
1227  fprintf(stderr,
1228  "InnoDB: dropping incompletely created"
1229  " SYS_FOREIGN table\n");
1230  row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
1231  }
1232 
1233  if (table2) {
1234  fprintf(stderr,
1235  "InnoDB: dropping incompletely created"
1236  " SYS_FOREIGN_COLS table\n");
1237  row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
1238  }
1239 
1240  fprintf(stderr,
1241  "InnoDB: Creating foreign key constraint system tables\n");
1242 
1243  /* NOTE: in dict_load_foreigns we use the fact that
1244  there are 2 secondary indexes on SYS_FOREIGN, and they
1245  are defined just like below */
1246 
1247  /* NOTE: when designing InnoDB's foreign key support in 2001, we made
1248  an error and made the table names and the foreign key id of type
1249  'CHAR' (internally, really a VARCHAR). We should have made the type
1250  VARBINARY, like in other InnoDB system tables, to get a clean
1251  design. */
1252 
1253  pars_info_t *info = pars_info_create();
1254  error = que_eval_sql(info,
1255  "PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
1256  "BEGIN\n"
1257  "CREATE TABLE\n"
1258  "SYS_FOREIGN(ID CHAR, FOR_NAME CHAR,"
1259  " REF_NAME CHAR, N_COLS INT);\n"
1260  "CREATE UNIQUE CLUSTERED INDEX ID_IND"
1261  " ON SYS_FOREIGN (ID);\n"
1262  "CREATE INDEX FOR_IND"
1263  " ON SYS_FOREIGN (FOR_NAME);\n"
1264  "CREATE INDEX REF_IND"
1265  " ON SYS_FOREIGN (REF_NAME);\n"
1266  "CREATE TABLE\n"
1267  "SYS_FOREIGN_COLS(ID CHAR, POS INT,"
1268  " FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n"
1269  "CREATE UNIQUE CLUSTERED INDEX ID_IND"
1270  " ON SYS_FOREIGN_COLS (ID, POS);\n"
1271  "END;\n"
1272  , FALSE, trx);
1273 
1274  if (error != DB_SUCCESS) {
1275  fprintf(stderr, "InnoDB: error %lu in creation\n",
1276  (ulong) error);
1277 
1278  ut_a(error == DB_OUT_OF_FILE_SPACE
1279  || error == DB_TOO_MANY_CONCURRENT_TRXS);
1280 
1281  fprintf(stderr,
1282  "InnoDB: creation failed\n"
1283  "InnoDB: tablespace is full\n"
1284  "InnoDB: dropping incompletely created"
1285  " SYS_FOREIGN tables\n");
1286 
1287  row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
1288  row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
1289 
1290  error = DB_MUST_GET_MORE_FILE_SPACE;
1291  }
1292 
1293  trx_commit_for_mysql(trx);
1294 
1296 
1297  trx_free_for_mysql(trx);
1298 
1299  if (error == DB_SUCCESS) {
1300  fprintf(stderr,
1301  "InnoDB: Foreign key constraint system tables"
1302  " created\n");
1303  }
1304 
1305  return(error);
1306 }
1307 
1308 /****************************************************************/
1311 static
1312 ulint
1313 dict_foreign_eval_sql(
1314 /*==================*/
1315  pars_info_t* info,
1316  const char* sql,
1317  dict_table_t* table,
1318  dict_foreign_t* foreign,
1319  trx_t* trx)
1320 {
1321  ulint error;
1322  FILE* ef = dict_foreign_err_file;
1323 
1324  error = que_eval_sql(info, sql, FALSE, trx);
1325 
1326  if (error == DB_DUPLICATE_KEY) {
1327  mutex_enter(&dict_foreign_err_mutex);
1328  rewind(ef);
1329  ut_print_timestamp(ef);
1330  fputs(" Error in foreign key constraint creation for table ",
1331  ef);
1332  ut_print_name(ef, trx, TRUE, table->name);
1333  fputs(".\nA foreign key constraint of name ", ef);
1334  ut_print_name(ef, trx, TRUE, foreign->id);
1335  fputs("\nalready exists."
1336  " (Note that internally InnoDB adds 'databasename'\n"
1337  "in front of the user-defined constraint name.)\n"
1338  "Note that InnoDB's FOREIGN KEY system tables store\n"
1339  "constraint names as case-insensitive, with the\n"
1340  "MySQL standard latin1_swedish_ci collation. If you\n"
1341  "create tables or databases whose names differ only in\n"
1342  "the character case, then collisions in constraint\n"
1343  "names can occur. Workaround: name your constraints\n"
1344  "explicitly with unique names.\n",
1345  ef);
1346 
1347  mutex_exit(&dict_foreign_err_mutex);
1348 
1349  return(error);
1350  }
1351 
1352  if (error != DB_SUCCESS) {
1353  fprintf(stderr,
1354  "InnoDB: Foreign key constraint creation failed:\n"
1355  "InnoDB: internal error number %lu\n", (ulong) error);
1356 
1357  mutex_enter(&dict_foreign_err_mutex);
1358  ut_print_timestamp(ef);
1359  fputs(" Internal error in foreign key constraint creation"
1360  " for table ", ef);
1361  ut_print_name(ef, trx, TRUE, table->name);
1362  fputs(".\n"
1363  "See the MySQL .err log in the datadir"
1364  " for more information.\n", ef);
1365  mutex_exit(&dict_foreign_err_mutex);
1366 
1367  return(error);
1368  }
1369 
1370  return(DB_SUCCESS);
1371 }
1372 
1373 /********************************************************************/
1377 static
1378 ulint
1379 dict_create_add_foreign_field_to_dictionary(
1380 /*========================================*/
1381  ulint field_nr,
1382  dict_table_t* table,
1383  dict_foreign_t* foreign,
1384  trx_t* trx)
1385 {
1386  pars_info_t* info = pars_info_create();
1387 
1388  pars_info_add_str_literal(info, "id", foreign->id);
1389 
1390  pars_info_add_int4_literal(info, "pos", field_nr);
1391 
1392  pars_info_add_str_literal(info, "for_col_name",
1393  foreign->foreign_col_names[field_nr]);
1394 
1395  pars_info_add_str_literal(info, "ref_col_name",
1396  foreign->referenced_col_names[field_nr]);
1397 
1398  return(dict_foreign_eval_sql(
1399  info,
1400  "PROCEDURE P () IS\n"
1401  "BEGIN\n"
1402  "INSERT INTO SYS_FOREIGN_COLS VALUES"
1403  "(:id, :pos, :for_col_name, :ref_col_name);\n"
1404  "END;\n",
1405  table, foreign, trx));
1406 }
1407 
1408 /********************************************************************/
1416 static
1417 ulint
1418 dict_create_add_foreign_to_dictionary(
1419 /*==================================*/
1420  ulint* id_nr,
1422  dict_table_t* table,
1423  dict_foreign_t* foreign,
1424  trx_t* trx)
1425 {
1426  ulint error;
1427  ulint i;
1428 
1429  pars_info_t* info = pars_info_create();
1430 
1431  if (foreign->id == NULL) {
1432  /* Generate a new constraint id */
1433  ulint namelen = strlen(table->name);
1434  char* id = static_cast<char *>(mem_heap_alloc(foreign->heap, namelen + 20));
1435  /* no overflow if number < 1e13 */
1436  sprintf(id, "%s_ibfk_%lu", table->name, (ulong) (*id_nr)++);
1437  foreign->id = id;
1438  }
1439 
1440  pars_info_add_str_literal(info, "id", foreign->id);
1441 
1442  pars_info_add_str_literal(info, "for_name", table->name);
1443 
1444  pars_info_add_str_literal(info, "ref_name",
1445  foreign->referenced_table_name);
1446 
1447  pars_info_add_int4_literal(info, "n_cols",
1448  foreign->n_fields + (foreign->type << 24));
1449 
1450  error = dict_foreign_eval_sql(info,
1451  "PROCEDURE P () IS\n"
1452  "BEGIN\n"
1453  "INSERT INTO SYS_FOREIGN VALUES"
1454  "(:id, :for_name, :ref_name, :n_cols);\n"
1455  "END;\n"
1456  , table, foreign, trx);
1457 
1458  if (error != DB_SUCCESS) {
1459 
1460  return(error);
1461  }
1462 
1463  for (i = 0; i < foreign->n_fields; i++) {
1464  error = dict_create_add_foreign_field_to_dictionary(
1465  i, table, foreign, trx);
1466 
1467  if (error != DB_SUCCESS) {
1468 
1469  return(error);
1470  }
1471  }
1472 
1473  error = dict_foreign_eval_sql(NULL,
1474  "PROCEDURE P () IS\n"
1475  "BEGIN\n"
1476  "COMMIT WORK;\n"
1477  "END;\n"
1478  , table, foreign, trx);
1479 
1480  return(error);
1481 }
1482 
1483 /********************************************************************/
1486 UNIV_INTERN
1487 ulint
1489 /*===================================*/
1490  ulint start_id,
1498  dict_table_t* table,
1499  trx_t* trx)
1500 {
1501  dict_foreign_t* foreign;
1502  ulint number = start_id + 1;
1503  ulint error;
1504 
1505  ut_ad(mutex_own(&(dict_sys->mutex)));
1506 
1507  if (NULL == dict_table_get_low("SYS_FOREIGN")) {
1508  fprintf(stderr,
1509  "InnoDB: table SYS_FOREIGN not found"
1510  " in internal data dictionary\n");
1511 
1512  return(DB_ERROR);
1513  }
1514 
1515  for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
1516  foreign;
1517  foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
1518 
1519  error = dict_create_add_foreign_to_dictionary(&number, table,
1520  foreign, trx);
1521 
1522  if (error != DB_SUCCESS) {
1523 
1524  return(error);
1525  }
1526  }
1527 
1528  return(DB_SUCCESS);
1529 }
#define UT_LIST_GET_LEN(BASE)
Definition: ut0lst.h:217
dict_table_t * sys_tables
Definition: dict0dict.h:1192
UNIV_INTERN ulint dict_create_or_check_foreign_constraint_tables(void)
Definition: dict0crea.cc:1193
UNIV_INTERN ins_node_t * ins_node_create(ulint ins_type, dict_table_t *table, mem_heap_t *heap)
Definition: row0ins.cc:69
UNIV_INTERN void trx_free_for_mysql(trx_t *trx)
Definition: trx0trx.cc:342
const char * name
Definition: dict0mem.h:339
UNIV_INTERN void dict_table_add_to_cache(dict_table_t *table, mem_heap_t *heap)
Definition: dict0dict.cc:827
dict_table_t * sys_fields
Definition: dict0dict.h:1195
#define UT_LIST_GET_NEXT(NAME, N)
Definition: ut0lst.h:201
#define FIL_IBD_FILE_INITIAL_SIZE
Definition: fil0fil.h:45
UNIV_INTERN ulint dict_create_add_foreigns_to_dictionary(ulint start_id, dict_table_t *table, trx_t *trx)
Definition: dict0crea.cc:1488
UNIV_INTERN ind_node_t * ind_create_graph_create(dict_index_t *index, mem_heap_t *heap)
Definition: dict0crea.cc:914
UNIV_INTERN const char * dict_table_get_col_name(const dict_table_t *table, ulint col_nr)
Definition: dict0dict.cc:374
trx_id_t id
Definition: trx0trx.h:548
unsigned n_def
Definition: dict0mem.h:502
UNIV_INLINE void mach_write_to_4(byte *b, ulint n)
unsigned space
Definition: dict0mem.h:343
unsigned type
Definition: dict0mem.h:347
table_id_t table_id
Definition: trx0trx.h:556
UNIV_INLINE dtuple_t * dtuple_create(mem_heap_t *heap, ulint n_fields)
UNIV_INTERN ulint dict_truncate_index_tree(dict_table_t *table, ulint space, btr_pcur_t *pcur, mtr_t *mtr)
Definition: dict0crea.cc:744
dict_table_t * sys_columns
Definition: dict0dict.h:1193
UNIV_INLINE ibool dict_table_is_comp(const dict_table_t *table)
UNIV_INLINE void mach_write_to_8(byte *b, ib_uint64_t n)
trx_id_t trx_id
Definition: dict0mem.h:401
mem_heap_t * heap
Definition: dict0mem.h:423
unsigned prtype
Definition: dict0mem.h:273
unsigned space
Definition: dict0mem.h:486
que_node_t * run_node
Definition: que0que.h:376
UNIV_INTERN void ins_node_set_new_row(ins_node_t *node, dtuple_t *row)
Definition: row0ins.cc:186
UNIV_INTERN ulint fil_space_get_zip_size(ulint id)
Definition: fil0fil.cc:1535
#define DICT_TF_FORMAT_ZIP
Definition: dict0mem.h:88
unsigned len
Definition: dict0mem.h:283
#define DICT_TF_BITS
Definition: dict0mem.h:100
#define btr_block_get(space, zip_size, page_no, mode, mtr)
Definition: btr0btr.h:212
UNIV_INTERN void pars_info_add_int4_literal(pars_info_t *info, const char *name, lint val)
Definition: pars0pars.cc:2027
#define DICT_TF_ZSSIZE_SHIFT
Definition: dict0mem.h:77
UNIV_INLINE void dfield_copy(dfield_t *field1, const dfield_t *field2)
unsigned page
Definition: dict0mem.h:345
UNIV_INTERN ulint trx_commit_for_mysql(trx_t *trx)
Definition: trx0trx.cc:1596
UNIV_INLINE dict_table_t * dict_table_get_low(const char *table_name)
char * referenced_table_name
Definition: dict0mem.h:441
que_common_t common
Definition: dict0crea.h:136
UNIV_INLINE void btr_pcur_close(btr_pcur_t *cursor)
UNIV_INTERN void dict_table_copy_types(dtuple_t *tuple, const dict_table_t *table)
Definition: dict0dict.cc:1963
que_common_t common
Definition: row0ins.h:113
UNIV_INTERN ulint btr_create(ulint type, ulint space, ulint zip_size, index_id_t index_id, dict_index_t *index, mtr_t *mtr)
Definition: btr0btr.cc:1287
dict_table_t * table
Definition: dict0crea.h:137
que_node_t * parent
Definition: que0types.h:49
UNIV_INTERN que_thr_t * dict_create_index_step(que_thr_t *thr)
Definition: dict0crea.cc:1058
UNIV_INTERN void pars_info_add_str_literal(pars_info_t *info, const char *name, const char *str)
Definition: pars0pars.cc:2006
UNIV_INTERN void mtr_commit(mtr_t *mtr) __attribute__((nonnull))
Definition: mtr0mtr.cc:247
UNIV_INTERN void dict_hdr_get_new_id(table_id_t *table_id, index_id_t *index_id, ulint *space_id)
Definition: dict0boot.cc:68
UNIV_INLINE void dfield_set_data(dfield_t *field, const void *data, ulint len)
dict_table_t * sys_indexes
Definition: dict0dict.h:1194
UNIV_INLINE ulint dict_table_zip_size(const dict_table_t *table)
const char ** referenced_col_names
Definition: dict0mem.h:446
UNIV_INTERN ulint mtr_read_ulint(const byte *ptr, ulint type, mtr_t *mtr)
Definition: mtr0mtr.cc:362
#define DICT_TF_FORMAT_MAX
Definition: dict0mem.h:94
const char * op_info
Definition: trx0trx.h:477
UNIV_INLINE ulint dict_table_get_format(const dict_table_t *table)
UNIV_INTERN ibool trx_is_strict(trx_t *trx)
Definition: ha_innodb.cc:1894
unsigned prefix_len
Definition: dict0mem.h:322
mem_heap_t * heap
Definition: dict0crea.h:152
table_id_t id
Definition: dict0mem.h:477
UNIV_INTERN dict_index_t * dict_index_get_if_in_cache_low(index_id_t index_id)
Definition: dict0dict.cc:4030
UNIV_INLINE ulint dict_index_is_clust(const dict_index_t *index) __attribute__((pure))
const char * name
Definition: dict0mem.h:321
UNIV_INTERN que_thr_t * dict_create_table_step(que_thr_t *thr)
Definition: dict0crea.cc:951
UNIV_INTERN void btr_pcur_store_position(btr_pcur_t *cursor, mtr_t *mtr)
Definition: btr0pcur.cc:89
UNIV_INTERN tab_node_t * tab_create_graph_create(dict_table_t *table, mem_heap_t *heap)
Definition: dict0crea.cc:878
#define ut_a(EXPR)
Definition: ut0dbg.h:105
UNIV_INTERN void ut_print_name(FILE *f, struct trx_struct *trx, ibool table_id, const char *name)
Definition: ut0ut.cc:528
UNIV_INTERN pars_info_t * pars_info_create(void)
Definition: pars0pars.cc:1938
UNIV_INLINE void * mem_heap_alloc(mem_heap_t *heap, ulint n)
#define mem_heap_create(N)
Definition: mem0mem.h:97
UNIV_INTERN ulint que_eval_sql(pars_info_t *info, const char *sql, ibool reserve_dict_mutex, trx_t *trx)
Definition: que0que.cc:1392
UNIV_INTERN ulint fil_create_new_single_table_tablespace(ulint space_id, const char *tablename, ibool is_temp, ulint flags, ulint size)
Definition: fil0fil.cc:2671
dict_table_t * table
Definition: dict0mem.h:341
UNIV_INLINE void * mem_heap_zalloc(mem_heap_t *heap, ulint n)
#define DICT_TF2_BITS
Definition: dict0mem.h:119
#define DICT_TF2_SHIFT
Additional table flags.
Definition: dict0mem.h:113
#define UT_LIST_GET_FIRST(BASE)
Definition: ut0lst.h:224
UNIV_INTERN ulint dict_index_add_to_cache(dict_table_t *table, dict_index_t *index, ulint page_no, ibool strict)
Definition: dict0dict.cc:1567
my_bool srv_file_per_table
Definition: srv0srv.cc:125
#define MLOG_4BYTES
Definition: mtr0mtr.h:75
dict_sys_t * dict_sys
Definition: dict0dict.cc:63
UNIV_INTERN void btr_free_but_not_root(ulint space, ulint zip_size, ulint root_page_no)
Definition: btr0btr.cc:1420
UNIV_INTERN trx_t * trx_allocate_for_mysql(void)
Definition: trx0trx.cc:199
dict_table_t * table
Definition: dict0crea.h:181
mem_heap_t * heap
Definition: dict0crea.h:184
index_id_t id
Definition: dict0mem.h:337
#define ut_ad(EXPR)
Definition: ut0dbg.h:127
#define DICT_TF_COMPACT
Definition: dict0mem.h:69
UNIV_INLINE que_node_t * que_node_get_parent(que_node_t *node)
unsigned flags
Definition: dict0mem.h:489
#define FIL_NULL
Definition: fil0fil.h:48
UNIV_INTERN void btr_free_root(ulint space, ulint zip_size, ulint root_page_no, mtr_t *mtr)
Definition: btr0btr.cc:1476
UNIV_INLINE ulint que_node_get_type(que_node_t *node)
const char * table_name
Definition: dict0mem.h:340
unsigned n_fields
Definition: dict0mem.h:361
UNIV_INLINE void dfield_set_null(dfield_t *field)
UNIV_INLINE ulint mach_read_from_4(const byte *b) __attribute__((nonnull
#define DICT_TABLE_ORDINARY
Definition: dict0mem.h:60
UNIV_INTERN void ut_print_timestamp(FILE *file)
Definition: ut0ut.cc:247
UNIV_INLINE trx_t * thr_get_trx(que_thr_t *thr)
que_node_t * prev_node
Definition: que0que.h:379
UNIV_INTERN commit_node_t * commit_node_create(mem_heap_t *heap)
Definition: trx0trx.cc:1530
UNIV_INLINE void mtr_start(mtr_t *mtr) __attribute__((nonnull))
que_common_t common
Definition: dict0crea.h:165
const char * dir_path_of_temp_table
Definition: dict0mem.h:480
que_common_t common
Definition: trx0trx.h:815
UNIV_INLINE ibool btr_pcur_move_to_next_user_rec(btr_pcur_t *cursor, mtr_t *mtr)
unsigned n_fields
Definition: dict0mem.h:427
dict_index_t * index
Definition: dict0crea.h:166
ulint error_state
Definition: trx0trx.h:601
UNIV_INLINE ib_uint64_t mach_read_from_8(const byte *b) __attribute__((nonnull
const char ** foreign_col_names
Definition: dict0mem.h:439
UNIV_INTERN void page_rec_write_index_page_no(rec_t *rec, ulint i, ulint page_no, mtr_t *mtr)
Definition: page0page.cc:1260
UNIV_INTERN void row_mysql_unlock_data_dictionary(trx_t *trx)
Definition: row0mysql.cc:1790
UNIV_INTERN int row_drop_table_for_mysql(const char *name, trx_t *trx, ibool drop_db)
Definition: row0mysql.cc:3033
UNIV_INTERN void fsp_header_init(ulint space, ulint size, mtr_t *mtr)
Definition: fsp0fsp.cc:951
unsigned mtype
Definition: dict0mem.h:272
UNIV_INTERN void dict_drop_index_tree(rec_t *rec, mtr_t *mtr)
Definition: dict0crea.cc:680
UNIV_INLINE ulint ut_strlen(const char *str)
UNIV_INTERN void dict_index_remove_from_cache(dict_table_t *table, dict_index_t *index)
Definition: dict0dict.cc:1734