~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Fix pidfile argument.

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
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
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
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
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
 
629
622
        ulint           num_created     = 0;
630
623
        ibool           dict_locked     = FALSE;
631
624
        ulint           new_primary;
632
 
        int             error;
 
625
        ulint           error;
633
626
 
634
627
        ut_a(i_table);
635
628
        ut_a(key_info);
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
 
        }
 
652
        /* Check that index keys are sensible */
663
653
 
664
 
        /* Check if the index name is reserved. */
665
 
        if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
666
 
                error = -1;
667
 
        } else {
668
 
                /* Check that index keys are sensible */
669
 
                error = innobase_check_index_keys(key_info, num_of_keys,
670
 
                                                  innodb_table);
671
 
        }
 
654
        error = innobase_check_index_keys(key_info, num_of_keys);
672
655
 
673
656
        if (UNIV_UNLIKELY(error)) {
674
657
err_exit:
675
658
                mem_heap_free(heap);
676
 
                trx_general_rollback_for_mysql(trx, NULL);
 
659
                trx_general_rollback_for_mysql(trx, FALSE, NULL);
677
660
                trx_free_for_mysql(trx);
678
661
                trx_commit_for_mysql(prebuilt->trx);
679
662
                return(error);
714
697
        row_mysql_lock_data_dictionary(trx);
715
698
        dict_locked = TRUE;
716
699
 
717
 
        ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
718
 
 
719
700
        /* If a new primary key is defined for the table we need
720
701
        to drop the original table and rebuild all indexes. */
721
702
 
748
729
                                        user_session);
749
730
                        }
750
731
 
751
 
                        ut_d(dict_table_check_for_dup_indexes(innodb_table,
752
 
                                                              FALSE));
753
732
                        row_mysql_unlock_data_dictionary(trx);
754
733
                        goto err_exit;
755
734
                }
774
753
 
775
754
        ut_ad(error == DB_SUCCESS);
776
755
 
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
756
        /* Commit the data dictionary transaction in order to release
782
 
        the table locks on the system tables.  This means that if
783
 
        MySQL crashes while creating a new primary key inside
784
 
        row_merge_build_indexes(), indexed_table will not be dropped
785
 
        by trx_rollback_active().  It will have to be recovered or
786
 
        dropped by the database administrator. */
 
757
        the table locks on the system tables.  Unfortunately, this
 
758
        means that if MySQL crashes while creating a new primary key
 
759
        inside row_merge_build_indexes(), indexed_table will not be
 
760
        dropped on crash recovery.  Thus, it will become orphaned. */
787
761
        trx_commit_for_mysql(trx);
788
762
 
789
763
        row_mysql_unlock_data_dictionary(trx);
813
787
                                        index, num_of_idx, i_table);
814
788
 
815
789
error_handling:
 
790
#ifdef UNIV_DEBUG
 
791
        /* TODO: At the moment we can't handle the following statement
 
792
        in our debugging code below:
 
793
 
 
794
        alter table t drop index b, add index (b);
 
795
 
 
796
        The fix will have to parse the SQL and note that the index
 
797
        being added has the same name as the the one being dropped and
 
798
        ignore that in the dup index check.*/
 
799
        //dict_table_check_for_dup_indexes(prebuilt->table);
 
800
#endif
816
801
 
817
802
        /* After an error, remove all those index definitions from the
818
803
        dictionary which were defined. */
825
810
                row_mysql_lock_data_dictionary(trx);
826
811
                dict_locked = TRUE;
827
812
 
828
 
                ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
829
 
 
830
813
                if (!new_primary) {
831
814
                        error = row_merge_rename_indexes(trx, indexed_table);
832
815
 
873
856
                indexed_table->n_mysql_handles_opened++;
874
857
 
875
858
                error = row_merge_drop_table(trx, innodb_table);
876
 
                innodb_table = indexed_table;
877
859
                goto convert_error;
878
860
 
879
861
        case DB_TOO_BIG_RECORD:
887
869
                prebuilt->trx->error_info = NULL;
888
870
                /* fall through */
889
871
        default:
890
 
                trx->error_state = DB_SUCCESS;
891
 
 
892
872
                if (new_primary) {
893
 
                        if (indexed_table != innodb_table) {
894
 
                                row_merge_drop_table(trx, indexed_table);
895
 
                        }
 
873
                        row_merge_drop_table(trx, indexed_table);
896
874
                } else {
897
875
                        if (!dict_locked) {
898
876
                                row_mysql_lock_data_dictionary(trx);
916
894
        }
917
895
 
918
896
        if (dict_locked) {
919
 
                ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
920
897
                row_mysql_unlock_data_dictionary(trx);
921
898
        }
922
899
 
959
936
        /* Test and mark all the indexes to be dropped */
960
937
 
961
938
        row_mysql_lock_data_dictionary(trx);
962
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
963
939
 
964
940
        /* Check that none of the indexes have previously been flagged
965
941
        for deletion. */
1005
981
                index->to_be_dropped = TRUE;
1006
982
        }
1007
983
 
1008
 
        /* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined
 
984
        /* If FOREIGN_KEY_CHECK = 1 you may not drop an index defined
1009
985
        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.
 
986
        tables contain indexes for the constraint.  Note that CREATE
 
987
        INDEX id ON table does a CREATE INDEX and DROP INDEX, and we
 
988
        can ignore here foreign keys because a new index for the
 
989
        foreign key has already been created.
1015
990
 
1016
991
        We check for the foreign key constraints after marking the
1017
992
        candidate indexes for deletion, because when we check for an
1126
1101
                } while (index);
1127
1102
        }
1128
1103
 
1129
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1130
1104
        row_mysql_unlock_data_dictionary(trx);
1131
1105
 
1132
1106
        return(err);
1171
1145
                prebuilt->table->flags, user_session);
1172
1146
 
1173
1147
        row_mysql_lock_data_dictionary(trx);
1174
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1175
1148
 
1176
1149
        if (UNIV_UNLIKELY(err)) {
1177
1150
 
1208
1181
                ut_a(!index->to_be_dropped);
1209
1182
        }
1210
1183
 
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;
 
1184
#ifdef UNIV_DEBUG
 
1185
        dict_table_check_for_dup_indexes(prebuilt->table);
 
1186
#endif
1214
1187
 
1215
1188
func_exit:
1216
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1217
1189
        trx_commit_for_mysql(trx);
1218
1190
        trx_commit_for_mysql(prebuilt->trx);
1219
1191
        row_mysql_unlock_data_dictionary(trx);