~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/dict/dict0crea.c

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
 
50
50
        entry = dtuple_create(heap, 8 + DATA_N_SYS_COLS);
51
51
 
 
52
        dict_table_copy_types(entry, sys_tables);
 
53
 
52
54
        /* 0: NAME -----------------------------*/
53
55
        dfield = dtuple_get_nth_field(entry, 0);
54
56
 
75
77
        dfield = dtuple_get_nth_field(entry, 3);
76
78
 
77
79
        ptr = mem_heap_alloc(heap, 4);
78
 
        mach_write_to_4(ptr, DICT_TABLE_ORDINARY);
 
80
        if (table->flags & ~DICT_TF_COMPACT) {
 
81
                ut_a(table->flags & DICT_TF_COMPACT);
 
82
                ut_a(dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP);
 
83
                ut_a((table->flags & DICT_TF_ZSSIZE_MASK)
 
84
                     <= (DICT_TF_ZSSIZE_MAX << DICT_TF_ZSSIZE_SHIFT));
 
85
                ut_a(!(table->flags & (~0 << DICT_TF_BITS)));
 
86
                mach_write_to_4(ptr, table->flags);
 
87
        } else {
 
88
                mach_write_to_4(ptr, DICT_TABLE_ORDINARY);
 
89
        }
79
90
 
80
91
        dfield_set_data(dfield, ptr, 4);
81
92
        /* 6: MIX_ID (obsolete) ---------------------------*/
82
93
        dfield = dtuple_get_nth_field(entry, 4);
83
94
 
84
 
        ptr = mem_heap_alloc(heap, 8);
85
 
        memset(ptr, 0, 8);
 
95
        ptr = mem_heap_zalloc(heap, 8);
86
96
 
87
97
        dfield_set_data(dfield, ptr, 8);
88
98
        /* 7: MIX_LEN (obsolete) --------------------------*/
89
99
 
90
100
        dfield = dtuple_get_nth_field(entry, 5);
91
101
 
92
 
        ptr = mem_heap_alloc(heap, 4);
93
 
        memset(ptr, 0, 4);
 
102
        ptr = mem_heap_zalloc(heap, 4);
94
103
 
95
104
        dfield_set_data(dfield, ptr, 4);
96
105
        /* 8: CLUSTER_NAME ---------------------*/
97
106
        dfield = dtuple_get_nth_field(entry, 6);
98
 
        dfield_set_data(dfield, NULL, UNIV_SQL_NULL); /* not supported */
 
107
        dfield_set_null(dfield); /* not supported */
99
108
 
100
109
        /* 9: SPACE ----------------------------*/
101
110
        dfield = dtuple_get_nth_field(entry, 7);
106
115
        dfield_set_data(dfield, ptr, 4);
107
116
        /*----------------------------------*/
108
117
 
109
 
        dict_table_copy_types(entry, sys_tables);
110
 
 
111
118
        return(entry);
112
119
}
113
120
 
139
146
 
140
147
        entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
141
148
 
 
149
        dict_table_copy_types(entry, sys_columns);
 
150
 
142
151
        /* 0: TABLE_ID -----------------------*/
143
152
        dfield = dtuple_get_nth_field(entry, 0);
144
153
 
188
197
        dfield_set_data(dfield, ptr, 4);
189
198
        /*---------------------------------*/
190
199
 
191
 
        dict_table_copy_types(entry, sys_columns);
192
 
 
193
200
        return(entry);
194
201
}
195
202
 
250
257
                        is_path = FALSE;
251
258
                }
252
259
 
 
260
                ut_ad(dict_table_get_format(table) <= DICT_TF_FORMAT_MAX);
 
261
                ut_ad(!dict_table_zip_size(table)
 
262
                      || dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP);
 
263
 
253
264
                error = fil_create_new_single_table_tablespace(
254
265
                        &space, path_or_name, is_path,
 
266
                        table->flags == DICT_TF_COMPACT ? 0 : table->flags,
255
267
                        FIL_IBD_FILE_INITIAL_SIZE);
256
268
                table->space = (unsigned int) space;
257
269
 
265
277
                fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
266
278
 
267
279
                mtr_commit(&mtr);
 
280
        } else {
 
281
                /* Create in the system tablespace: disallow new features */
 
282
                table->flags &= DICT_TF_COMPACT;
268
283
        }
269
284
 
270
285
        row = dict_create_sys_tables_tuple(table, node->heap);
319
334
 
320
335
        entry = dtuple_create(heap, 7 + DATA_N_SYS_COLS);
321
336
 
 
337
        dict_table_copy_types(entry, sys_indexes);
 
338
 
322
339
        /* 0: TABLE_ID -----------------------*/
323
340
        dfield = dtuple_get_nth_field(entry, 0);
324
341
 
377
394
        dfield_set_data(dfield, ptr, 4);
378
395
        /*--------------------------------*/
379
396
 
380
 
        dict_table_copy_types(entry, sys_indexes);
381
 
 
382
397
        return(entry);
383
398
}
384
399
 
408
423
        for (j = 0; j < index->n_fields; j++) {
409
424
                if (dict_index_get_nth_field(index, j)->prefix_len > 0) {
410
425
                        index_contains_column_prefix_field = TRUE;
 
426
                        break;
411
427
                }
412
428
        }
413
429
 
417
433
 
418
434
        entry = dtuple_create(heap, 3 + DATA_N_SYS_COLS);
419
435
 
 
436
        dict_table_copy_types(entry, sys_fields);
 
437
 
420
438
        /* 0: INDEX_ID -----------------------*/
421
439
        dfield = dtuple_get_nth_field(entry, 0);
422
440
 
452
470
                        ut_strlen(field->name));
453
471
        /*---------------------------------*/
454
472
 
455
 
        dict_table_copy_types(entry, sys_fields);
456
 
 
457
473
        return(entry);
458
474
}
459
475
 
465
481
dict_create_search_tuple(
466
482
/*=====================*/
467
483
                                /* out: the tuple for search */
468
 
        dtuple_t*       tuple,  /* in: the tuple inserted in the SYS_INDEXES
 
484
        const dtuple_t* tuple,  /* in: the tuple inserted in the SYS_INDEXES
469
485
                                table */
470
486
        mem_heap_t*     heap)   /* in: memory heap from which the memory for
471
487
                                the built tuple is allocated */
472
488
{
473
489
        dtuple_t*       search_tuple;
474
 
        dfield_t*       field1;
 
490
        const dfield_t* field1;
475
491
        dfield_t*       field2;
476
492
 
477
493
        ut_ad(tuple && heap);
525
541
        node->table = table;
526
542
 
527
543
        ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
528
 
              || (index->type & DICT_CLUSTERED));
 
544
              || dict_index_is_clust(index));
529
545
 
530
 
        index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
 
546
        /* For fast index creation we have already allocated an index id
 
547
        for this index so that we could write an UNDO log record for it.*/
 
548
        if (ut_dulint_is_zero(index->id)) {
 
549
                index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
 
550
        }
531
551
 
532
552
        /* Inherit the space id from the table; we store all indexes of a
533
553
        table in the same tablespace */
539
559
 
540
560
        ins_node_set_new_row(node->ind_def, row);
541
561
 
 
562
#ifdef ROW_MERGE_IS_INDEX_USABLE
 
563
        /* Note that the index was created by this transaction. */
 
564
        index->trx_id = trx->id;
 
565
#endif /* ROW_MERGE_IS_INDEX_USABLE */
 
566
 
542
567
        return(DB_SUCCESS);
543
568
}
544
569
 
600
625
 
601
626
        btr_pcur_move_to_next_user_rec(&pcur, &mtr);
602
627
 
603
 
        node->page_no = btr_create(index->type, index->space, index->id,
604
 
                                   dict_table_is_comp(table), &mtr);
 
628
        node->page_no = btr_create(index->type, index->space,
 
629
                                   dict_table_zip_size(index->table),
 
630
                                   index->id, index, &mtr);
605
631
        /* printf("Created a new index tree in space %lu root page %lu\n",
606
632
        index->space, index->page_no); */
607
633
 
621
647
 
622
648
/***********************************************************************
623
649
Drops the index tree associated with a row in SYS_INDEXES table. */
624
 
 
 
650
UNIV_INTERN
625
651
void
626
652
dict_drop_index_tree(
627
653
/*=================*/
628
 
        rec_t*  rec,    /* in: record in the clustered index of SYS_INDEXES
629
 
                        table */
 
654
        rec_t*  rec,    /* in/out: record in the clustered index
 
655
                        of SYS_INDEXES table */
630
656
        mtr_t*  mtr)    /* in: mtr having the latch on the record page */
631
657
{
632
 
        ulint   root_page_no;
633
 
        ulint   space;
634
 
        byte*   ptr;
635
 
        ulint   len;
 
658
        ulint           root_page_no;
 
659
        ulint           space;
 
660
        ulint           zip_size;
 
661
        const byte*     ptr;
 
662
        ulint           len;
636
663
 
637
664
        ut_ad(mutex_own(&(dict_sys->mutex)));
638
665
        ut_a(!dict_table_is_comp(dict_sys->sys_indexes));
654
681
        ut_ad(len == 4);
655
682
 
656
683
        space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
 
684
        zip_size = fil_space_get_zip_size(space);
657
685
 
658
 
        if (!fil_tablespace_exists_in_mem(space)) {
 
686
        if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
659
687
                /* It is a single table tablespace and the .ibd file is
660
688
                missing: do nothing */
661
689
 
665
693
        /* We free all the pages but the root page first; this operation
666
694
        may span several mini-transactions */
667
695
 
668
 
        btr_free_but_not_root(space, root_page_no);
 
696
        btr_free_but_not_root(space, zip_size, root_page_no);
669
697
 
670
698
        /* Then we free the root page in the same mini-transaction where
671
699
        we write FIL_NULL to the appropriate field in the SYS_INDEXES
673
701
 
674
702
        /* printf("Dropping index tree in space %lu root page %lu\n", space,
675
703
        root_page_no); */
676
 
        btr_free_root(space, root_page_no, mtr);
 
704
        btr_free_root(space, zip_size, root_page_no, mtr);
677
705
 
678
706
        page_rec_write_index_page_no(rec,
679
707
                                     DICT_SYS_INDEXES_PAGE_NO_FIELD,
682
710
 
683
711
/***********************************************************************
684
712
Truncates the index tree associated with a row in SYS_INDEXES table. */
685
 
 
 
713
UNIV_INTERN
686
714
ulint
687
715
dict_truncate_index_tree(
688
716
/*=====================*/
689
717
                                /* out: new root page number, or
690
718
                                FIL_NULL on failure */
691
719
        dict_table_t*   table,  /* in: the table the index belongs to */
 
720
        ulint           space,  /* in: 0=truncate,
 
721
                                nonzero=create the index tree in the
 
722
                                given tablespace */
692
723
        btr_pcur_t*     pcur,   /* in/out: persistent cursor pointing to
693
724
                                record in the clustered index of
694
725
                                SYS_INDEXES table. The cursor may be
698
729
                                committed and restarted in this call. */
699
730
{
700
731
        ulint           root_page_no;
701
 
        ulint           space;
 
732
        ibool           drop = !space;
 
733
        ulint           zip_size;
702
734
        ulint           type;
703
735
        dulint          index_id;
704
736
        rec_t*          rec;
705
 
        byte*           ptr;
 
737
        const byte*     ptr;
706
738
        ulint           len;
707
 
        ulint           comp;
708
739
        dict_index_t*   index;
709
740
 
710
741
        ut_ad(mutex_own(&(dict_sys->mutex)));
716
747
 
717
748
        root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
718
749
 
719
 
        if (root_page_no == FIL_NULL) {
 
750
        if (drop && root_page_no == FIL_NULL) {
720
751
                /* The tree has been freed. */
721
752
 
722
753
                ut_print_timestamp(stderr);
723
754
                fprintf(stderr, "  InnoDB: Trying to TRUNCATE"
724
755
                        " a missing index of table %s!\n", table->name);
725
 
                return(FIL_NULL);
 
756
                drop = FALSE;
726
757
        }
727
758
 
728
759
        ptr = rec_get_nth_field_old(rec,
730
761
 
731
762
        ut_ad(len == 4);
732
763
 
733
 
        space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
734
 
 
735
 
        if (!fil_tablespace_exists_in_mem(space)) {
 
764
        if (drop) {
 
765
                space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
 
766
        }
 
767
 
 
768
        zip_size = fil_space_get_zip_size(space);
 
769
 
 
770
        if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
736
771
                /* It is a single table tablespace and the .ibd file is
737
772
                missing: do nothing */
738
773
 
751
786
        ut_ad(len == 8);
752
787
        index_id = mach_read_from_8(ptr);
753
788
 
 
789
        if (!drop) {
 
790
 
 
791
                goto create;
 
792
        }
 
793
 
754
794
        /* We free all the pages but the root page first; this operation
755
795
        may span several mini-transactions */
756
796
 
757
 
        btr_free_but_not_root(space, root_page_no);
 
797
        btr_free_but_not_root(space, zip_size, root_page_no);
758
798
 
759
799
        /* Then we free the root page in the same mini-transaction where
760
800
        we create the b-tree and write its new root page number to the
761
801
        appropriate field in the SYS_INDEXES record: this mini-transaction
762
802
        marks the B-tree totally truncated */
763
803
 
764
 
        comp = page_is_comp(btr_page_get(space, root_page_no, RW_X_LATCH,
765
 
                                         mtr));
 
804
        btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
766
805
 
767
 
        btr_free_root(space, root_page_no, mtr);
 
806
        btr_free_root(space, zip_size, root_page_no, mtr);
 
807
create:
768
808
        /* We will temporarily write FIL_NULL to the PAGE_NO field
769
809
        in SYS_INDEXES, so that the database will not get into an
770
810
        inconsistent state in case it crashes between the mtr_commit()
786
826
             index;
787
827
             index = UT_LIST_GET_NEXT(indexes, index)) {
788
828
                if (!ut_dulint_cmp(index->id, index_id)) {
789
 
                        break;
 
829
                        root_page_no = btr_create(type, space, zip_size,
 
830
                                                  index_id, index, mtr);
 
831
                        index->page = (unsigned int) root_page_no;
 
832
                        return(root_page_no);
790
833
                }
791
834
        }
792
835
 
793
 
        root_page_no = btr_create(type, space, index_id, comp, mtr);
794
 
        if (index) {
795
 
                index->page = (unsigned int) root_page_no;
796
 
        } else {
797
 
                ut_print_timestamp(stderr);
798
 
                fprintf(stderr,
799
 
                        "  InnoDB: Index %lu %lu of table %s is missing\n"
800
 
                        "InnoDB: from the data dictionary during TRUNCATE!\n",
801
 
                        ut_dulint_get_high(index_id),
802
 
                        ut_dulint_get_low(index_id),
803
 
                        table->name);
804
 
        }
 
836
        ut_print_timestamp(stderr);
 
837
        fprintf(stderr,
 
838
                "  InnoDB: Index %lu %lu of table %s is missing\n"
 
839
                "InnoDB: from the data dictionary during TRUNCATE!\n",
 
840
                ut_dulint_get_high(index_id),
 
841
                ut_dulint_get_low(index_id),
 
842
                table->name);
805
843
 
806
 
        return(root_page_no);
 
844
        return(FIL_NULL);
807
845
}
808
846
 
809
847
/*************************************************************************
810
848
Creates a table create graph. */
811
 
 
 
849
UNIV_INTERN
812
850
tab_node_t*
813
851
tab_create_graph_create(
814
852
/*====================*/
844
882
 
845
883
/*************************************************************************
846
884
Creates an index create graph. */
847
 
 
 
885
UNIV_INTERN
848
886
ind_node_t*
849
887
ind_create_graph_create(
850
888
/*====================*/
881
919
 
882
920
/***************************************************************
883
921
Creates a table. This is a high-level function used in SQL execution graphs. */
884
 
 
 
922
UNIV_INTERN
885
923
que_thr_t*
886
924
dict_create_table_step(
887
925
/*===================*/
988
1026
/***************************************************************
989
1027
Creates an index. This is a high-level function used in SQL execution
990
1028
graphs. */
991
 
 
 
1029
UNIV_INTERN
992
1030
que_thr_t*
993
1031
dict_create_index_step(
994
1032
/*===================*/
1046
1084
 
1047
1085
                        return(thr);
1048
1086
                } else {
1049
 
                        node->state = INDEX_CREATE_INDEX_TREE;
1050
 
                }
 
1087
                        node->state = INDEX_ADD_TO_CACHE;
 
1088
                }
 
1089
        }
 
1090
 
 
1091
        if (node->state == INDEX_ADD_TO_CACHE) {
 
1092
 
 
1093
                dulint  index_id = node->index->id;
 
1094
 
 
1095
                err = dict_index_add_to_cache(node->table, node->index,
 
1096
                                              FIL_NULL);
 
1097
 
 
1098
                node->index = dict_index_get_if_in_cache_low(index_id);
 
1099
                ut_a(!node->index == (err != DB_SUCCESS));
 
1100
 
 
1101
                if (err != DB_SUCCESS) {
 
1102
 
 
1103
                        goto function_exit;
 
1104
                }
 
1105
 
 
1106
                node->state = INDEX_CREATE_INDEX_TREE;
1051
1107
        }
1052
1108
 
1053
1109
        if (node->state == INDEX_CREATE_INDEX_TREE) {
1055
1111
                err = dict_create_index_tree_step(node);
1056
1112
 
1057
1113
                if (err != DB_SUCCESS) {
 
1114
                        dict_index_remove_from_cache(node->table, node->index);
 
1115
                        node->index = NULL;
1058
1116
 
1059
1117
                        goto function_exit;
1060
1118
                }
1061
1119
 
 
1120
                node->index->page = node->page_no;
1062
1121
                node->state = INDEX_COMMIT_WORK;
1063
1122
        }
1064
1123
 
1068
1127
                (CREATE INDEX does NOT currently do an implicit commit of
1069
1128
                the current transaction) */
1070
1129
 
1071
 
                node->state = INDEX_ADD_TO_CACHE;
 
1130
                node->state = INDEX_CREATE_INDEX_TREE;
1072
1131
 
1073
1132
                /* thr->run_node = node->commit_node;
1074
1133
 
1075
1134
                return(thr); */
1076
1135
        }
1077
1136
 
1078
 
        if (node->state == INDEX_ADD_TO_CACHE) {
1079
 
 
1080
 
                dict_index_add_to_cache(node->table, node->index,
1081
 
                                        node->page_no);
1082
 
 
1083
 
                err = DB_SUCCESS;
1084
 
        }
1085
 
 
1086
1137
function_exit:
1087
1138
        trx->error_state = err;
1088
1139
 
1103
1154
        return(thr);
1104
1155
}
1105
1156
 
 
1157
#ifndef UNIV_HOTBACKUP
1106
1158
/********************************************************************
1107
1159
Creates the foreign key constraints system tables inside InnoDB
1108
1160
at database creation or database start if they are not found or are
1109
1161
not of the right form. */
1110
 
 
 
1162
UNIV_INTERN
1111
1163
ulint
1112
1164
dict_create_or_check_foreign_constraint_tables(void)
1113
1165
/*================================================*/
1227
1279
 
1228
1280
/********************************************************************
1229
1281
Evaluate the given foreign key SQL statement. */
1230
 
 
1231
 
static ulint
 
1282
static
 
1283
ulint
1232
1284
dict_foreign_eval_sql(
1233
1285
/*==================*/
1234
1286
                                /* out: error code or DB_SUCCESS */
1251
1303
                      ef);
1252
1304
                ut_print_name(ef, trx, TRUE, table->name);
1253
1305
                fputs(".\nA foreign key constraint of name ", ef);
1254
 
                ut_print_name(ef, trx, FALSE, foreign->id);
 
1306
                ut_print_name(ef, trx, TRUE, foreign->id);
1255
1307
                fputs("\nalready exists."
1256
 
                      " (Note that internally InnoDB adds 'databasename/'\n"
1257
 
                      "in front of the user-defined constraint name).\n",
1258
 
                      ef);
1259
 
                fputs("Note that InnoDB's FOREIGN KEY system tables store\n"
 
1308
                      " (Note that internally InnoDB adds 'databasename'\n"
 
1309
                      "in front of the user-defined constraint name.)\n"
 
1310
                      "Note that InnoDB's FOREIGN KEY system tables store\n"
1260
1311
                      "constraint names as case-insensitive, with the\n"
1261
1312
                      "MySQL standard latin1_swedish_ci collation. If you\n"
1262
1313
                      "create tables or databases whose names differ only in\n"
1403
1454
 
1404
1455
/************************************************************************
1405
1456
Adds foreign key definitions to data dictionary tables in the database. */
1406
 
 
 
1457
UNIV_INTERN
1407
1458
ulint
1408
1459
dict_create_add_foreigns_to_dictionary(
1409
1460
/*===================================*/
1448
1499
 
1449
1500
        return(DB_SUCCESS);
1450
1501
}
 
1502
#endif /* !UNIV_HOTBACKUP */