~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/handler/handler0alter.cc

  • Committer: Brian Aker
  • Date: 2010-10-28 17:12:01 UTC
  • mfrom: (1887.1.3 merge)
  • Revision ID: brian@tangent.org-20101028171201-baj6l1bnntn1s4ad
Merge in POTFILES changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 2005, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 2005, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
29
29
#include <drizzled/field/varstring.h>
30
30
#include "drizzled/internal/my_sys.h"
31
31
 
 
32
extern "C" {
32
33
#include "log0log.h"
33
34
#include "row0merge.h"
34
35
#include "srv0srv.h"
36
37
#include "trx0roll.h"
37
38
#include "ha_prototypes.h"
38
39
#include "handler0alter.h"
 
40
}
39
41
 
40
42
#include "ha_innodb.h"
41
43
#include "handler0vars.h"
101
103
#ifdef UNIV_DEBUG
102
104
        case DATA_MYSQL:
103
105
                ut_ad(flen >= len);
104
 
                ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
105
 
                      >= DATA_MBMINLEN(col->mbminmaxlen));
106
 
                ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
107
 
                      > DATA_MBMINLEN(col->mbminmaxlen) || flen == len);
 
106
                ut_ad(col->mbmaxlen >= col->mbminlen);
 
107
                ut_ad(col->mbmaxlen > col->mbminlen || flen == len);
108
108
                memcpy(dest, data, len);
109
109
                break;
110
110
 
130
130
 
131
131
/*************************************************************//**
132
132
Copies an InnoDB record to table->getInsertRecord(). */
133
 
UNIV_INTERN
 
133
extern "C" UNIV_INTERN
134
134
void
135
135
innobase_rec_to_mysql(
136
136
/*==================*/
180
180
 
181
181
/*************************************************************//**
182
182
Resets table->getInsertRecord(). */
183
 
UNIV_INTERN
 
183
extern "C" UNIV_INTERN
184
184
void
185
185
innobase_rec_reset(
186
186
/*===============*/
231
231
innobase_check_index_keys(
232
232
/*======================*/
233
233
        const KeyInfo*  key_info,       /*!< in: Indexes to be created */
234
 
        ulint           num_of_keys,    /*!< in: Number of indexes to
 
234
        ulint           num_of_keys)    /*!< in: Number of indexes to
235
235
                                        be created */
236
 
        const dict_table_t*     table)  /*!< in: Existing indexes */
237
236
{
238
237
        ulint           key_num;
239
238
 
250
249
                        const KeyInfo&  key2 = key_info[i];
251
250
 
252
251
                        if (0 == strcmp(key.name, key2.name)) {
253
 
                                my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
254
 
                                         key.name);
255
 
 
256
 
                                return(ER_WRONG_NAME_FOR_INDEX);
257
 
                        }
258
 
                }
259
 
 
260
 
                /* Check that the same index name does not already exist. */
261
 
 
262
 
                for (const dict_index_t* index
263
 
                             = dict_table_get_first_index(table);
264
 
                     index; index = dict_table_get_next_index(index)) {
265
 
 
266
 
                        if (0 == strcmp(key.name, index->name)) {
267
 
                                my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
268
 
                                         key.name);
 
252
                                errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: key name `%s` appears"
 
253
                                                " twice in CREATE INDEX\n",
 
254
                                                key.name);
269
255
 
270
256
                                return(ER_WRONG_NAME_FOR_INDEX);
271
257
                        }
273
259
 
274
260
                /* Check that MySQL does not try to create a column
275
261
                prefix index field on an inappropriate data type and
276
 
                that the same column does not appear twice in the index. */
 
262
                that the same colum does not appear twice in the index. */
277
263
 
278
264
                for (ulint i = 0; i < key.key_parts; i++) {
279
265
                        const KeyPartInfo&      key_part1
304
290
                                        }
305
291
                                }
306
292
 
307
 
                                my_error(ER_WRONG_KEY_COLUMN, MYF(0),
308
 
                                         field->field_name);
 
293
                                errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: MySQL is trying to"
 
294
                                                " create a column prefix"
 
295
                                                " index field on an"
 
296
                                                " inappropriate data type."
 
297
                                                " column `%s`,"
 
298
                                                " index `%s`.\n",
 
299
                                                field->field_name,
 
300
                                                key.name);
309
301
                                return(ER_WRONG_KEY_COLUMN);
310
302
                        }
311
303
 
318
310
                                        continue;
319
311
                                }
320
312
 
321
 
                                my_error(ER_WRONG_KEY_COLUMN, MYF(0),
322
 
                                         key_part1.field->field_name);
 
313
                                errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: column `%s`"
 
314
                                                " is not allowed to occur"
 
315
                                                " twice in index `%s`.\n",
 
316
                                                key_part1.field->field_name,
 
317
                                                key.name);
323
318
                                return(ER_WRONG_KEY_COLUMN);
324
319
                        }
325
320
                }
520
515
                                     key_info->name, "PRIMARY");
521
516
 
522
517
        /* If there is a UNIQUE INDEX consisting entirely of NOT NULL
523
 
        columns and if the index does not contain column prefix(es)
524
 
        (only prefix/part of the column is indexed), MySQL will treat the
525
 
        index as a PRIMARY KEY unless the table already has one. */
 
518
        columns, MySQL will treat it as a PRIMARY KEY unless the
 
519
        table already has one. */
526
520
 
527
521
        if (!new_primary && (key_info->flags & HA_NOSAME)
528
 
            && (!(key_info->flags & HA_KEY_HAS_PART_KEY_SEG))
529
522
            && row_table_got_default_clust_index(table)) {
530
 
                uint    key_part = key_info->key_parts;
 
523
                uint    key_part = key_info->key_parts;
531
524
 
532
525
                new_primary = TRUE;
533
526
 
656
649
        innodb_table = indexed_table
657
650
                = dict_table_get(prebuilt->table->name, FALSE);
658
651
 
659
 
        if (UNIV_UNLIKELY(!innodb_table)) {
660
 
                error = HA_ERR_NO_SUCH_TABLE;
661
 
                goto err_exit;
662
 
        }
663
 
 
664
652
        /* Check if the index name is reserved. */
665
653
        if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
666
654
                error = -1;
667
655
        } else {
668
656
                /* Check that index keys are sensible */
669
 
                error = innobase_check_index_keys(key_info, num_of_keys,
670
 
                                                  innodb_table);
 
657
                error = innobase_check_index_keys(key_info, num_of_keys);
671
658
        }
672
659
 
673
660
        if (UNIV_UNLIKELY(error)) {
714
701
        row_mysql_lock_data_dictionary(trx);
715
702
        dict_locked = TRUE;
716
703
 
717
 
        ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
718
 
 
719
704
        /* If a new primary key is defined for the table we need
720
705
        to drop the original table and rebuild all indexes. */
721
706
 
748
733
                                        user_session);
749
734
                        }
750
735
 
751
 
                        ut_d(dict_table_check_for_dup_indexes(innodb_table,
752
 
                                                              FALSE));
753
736
                        row_mysql_unlock_data_dictionary(trx);
754
737
                        goto err_exit;
755
738
                }
774
757
 
775
758
        ut_ad(error == DB_SUCCESS);
776
759
 
777
 
        /* We will need to rebuild index translation table. Set
778
 
        valid index entry count in the translation table to zero */
779
 
        share->idx_trans_tbl.index_count = 0;
780
 
 
781
760
        /* Commit the data dictionary transaction in order to release
782
761
        the table locks on the system tables.  This means that if
783
762
        MySQL crashes while creating a new primary key inside
813
792
                                        index, num_of_idx, i_table);
814
793
 
815
794
error_handling:
 
795
#ifdef UNIV_DEBUG
 
796
        /* TODO: At the moment we can't handle the following statement
 
797
        in our debugging code below:
 
798
 
 
799
        alter table t drop index b, add index (b);
 
800
 
 
801
        The fix will have to parse the SQL and note that the index
 
802
        being added has the same name as the the one being dropped and
 
803
        ignore that in the dup index check.*/
 
804
        //dict_table_check_for_dup_indexes(prebuilt->table);
 
805
#endif
816
806
 
817
807
        /* After an error, remove all those index definitions from the
818
808
        dictionary which were defined. */
825
815
                row_mysql_lock_data_dictionary(trx);
826
816
                dict_locked = TRUE;
827
817
 
828
 
                ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
829
 
 
830
818
                if (!new_primary) {
831
819
                        error = row_merge_rename_indexes(trx, indexed_table);
832
820
 
887
875
                prebuilt->trx->error_info = NULL;
888
876
                /* fall through */
889
877
        default:
890
 
                trx->error_state = DB_SUCCESS;
891
 
 
892
878
                if (new_primary) {
893
879
                        if (indexed_table != innodb_table) {
894
880
                                row_merge_drop_table(trx, indexed_table);
916
902
        }
917
903
 
918
904
        if (dict_locked) {
919
 
                ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
920
905
                row_mysql_unlock_data_dictionary(trx);
921
906
        }
922
907
 
959
944
        /* Test and mark all the indexes to be dropped */
960
945
 
961
946
        row_mysql_lock_data_dictionary(trx);
962
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
963
947
 
964
948
        /* Check that none of the indexes have previously been flagged
965
949
        for deletion. */
1005
989
                index->to_be_dropped = TRUE;
1006
990
        }
1007
991
 
1008
 
        /* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined
 
992
        /* If FOREIGN_KEY_CHECK = 1 you may not drop an index defined
1009
993
        for a foreign key constraint because InnoDB requires that both
1010
 
        tables contain indexes for the constraint. Such index can
1011
 
        be dropped only if FOREIGN_KEY_CHECKS is set to 0.
1012
 
        Note that CREATE INDEX id ON table does a CREATE INDEX and
1013
 
        DROP INDEX, and we can ignore here foreign keys because a
1014
 
        new index for the foreign key has already been created.
 
994
        tables contain indexes for the constraint.  Note that CREATE
 
995
        INDEX id ON table does a CREATE INDEX and DROP INDEX, and we
 
996
        can ignore here foreign keys because a new index for the
 
997
        foreign key has already been created.
1015
998
 
1016
999
        We check for the foreign key constraints after marking the
1017
1000
        candidate indexes for deletion, because when we check for an
1126
1109
                } while (index);
1127
1110
        }
1128
1111
 
1129
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1130
1112
        row_mysql_unlock_data_dictionary(trx);
1131
1113
 
1132
1114
        return(err);
1171
1153
                prebuilt->table->flags, user_session);
1172
1154
 
1173
1155
        row_mysql_lock_data_dictionary(trx);
1174
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1175
1156
 
1176
1157
        if (UNIV_UNLIKELY(err)) {
1177
1158
 
1208
1189
                ut_a(!index->to_be_dropped);
1209
1190
        }
1210
1191
 
1211
 
        /* We will need to rebuild index translation table. Set
1212
 
        valid index entry count in the translation table to zero */
1213
 
        share->idx_trans_tbl.index_count = 0;
 
1192
#ifdef UNIV_DEBUG
 
1193
        dict_table_check_for_dup_indexes(prebuilt->table);
 
1194
#endif
1214
1195
 
1215
1196
func_exit:
1216
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1217
1197
        trx_commit_for_mysql(trx);
1218
1198
        trx_commit_for_mysql(prebuilt->trx);
1219
1199
        row_mysql_unlock_data_dictionary(trx);