~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-10 19:32:58 UTC
  • Revision ID: brian@tangent.org-20101010193258-uvwhrqqpbd2e065x
Added support for pre/post triggers (this removes the need for the current
logging system I believe).

Add test cases to existing triggers.

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
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. */
1125
1101
                } while (index);
1126
1102
        }
1127
1103
 
1128
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1129
1104
        row_mysql_unlock_data_dictionary(trx);
1130
1105
 
1131
1106
        return(err);
1170
1145
                prebuilt->table->flags, user_session);
1171
1146
 
1172
1147
        row_mysql_lock_data_dictionary(trx);
1173
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1174
1148
 
1175
1149
        if (UNIV_UNLIKELY(err)) {
1176
1150
 
1207
1181
                ut_a(!index->to_be_dropped);
1208
1182
        }
1209
1183
 
1210
 
        /* We will need to rebuild index translation table. Set
1211
 
        valid index entry count in the translation table to zero */
1212
 
        share->idx_trans_tbl.index_count = 0;
 
1184
#ifdef UNIV_DEBUG
 
1185
        dict_table_check_for_dup_indexes(prebuilt->table);
 
1186
#endif
1213
1187
 
1214
1188
func_exit:
1215
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1216
1189
        trx_commit_for_mysql(trx);
1217
1190
        trx_commit_for_mysql(prebuilt->trx);
1218
1191
        row_mysql_unlock_data_dictionary(trx);