~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-08-18 07:20:29 UTC
  • mfrom: (1117.1.9 merge)
  • Revision ID: brian@gaz-20090818072029-s9ch5lcmltxwidn7
Merge of Brian

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
 
19
 
/**************************************************//**
20
 
@file handler/handler0alter.cc
 
19
/******************************************************
21
20
Smart ALTER TABLE
22
21
*******************************************************/
23
22
 
24
 
#include <config.h>
 
23
#include <drizzled/server_includes.h>
25
24
#include <drizzled/error.h>
26
 
#include <drizzled/charset_info.h>
 
25
#include <mystrings/m_ctype.h>
27
26
#include <drizzled/field.h>
28
27
#include <drizzled/table.h>
29
28
#include <drizzled/field/varstring.h>
30
 
#include <drizzled/internal/my_sys.h>
31
29
 
 
30
extern "C" {
32
31
#include "log0log.h"
33
32
#include "row0merge.h"
34
33
#include "srv0srv.h"
36
35
#include "trx0roll.h"
37
36
#include "ha_prototypes.h"
38
37
#include "handler0alter.h"
 
38
}
39
39
 
40
40
#include "ha_innodb.h"
41
41
#include "handler0vars.h"
42
42
 
43
 
/*************************************************************//**
 
43
/*****************************************************************
44
44
Copies an InnoDB column to a MySQL field.  This function is
45
45
adapted from row_sel_field_store_in_mysql_format(). */
46
46
static
47
47
void
48
48
innobase_col_to_mysql(
49
49
/*==================*/
50
 
        const dict_col_t*       col,    /*!< in: InnoDB column */
51
 
        const unsigned char*    data,   /*!< in: InnoDB column data */
52
 
        ulint                   len,    /*!< in: length of data, in bytes */
53
 
        Field*                  field)  /*!< in/out: MySQL field */
 
50
        const dict_col_t*       col,    /* in: InnoDB column */
 
51
        const unsigned char*            data,   /* in: InnoDB column data */
 
52
        ulint                   len,    /* in: length of data, in bytes */
 
53
        Field*                  field)  /* in/out: MySQL field */
54
54
{
55
55
        unsigned char*  ptr;
56
56
        unsigned char*  dest    = field->ptr;
101
101
#ifdef UNIV_DEBUG
102
102
        case DATA_MYSQL:
103
103
                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);
 
104
                ut_ad(col->mbmaxlen >= col->mbminlen);
 
105
                ut_ad(col->mbmaxlen > col->mbminlen || flen == len);
108
106
                memcpy(dest, data, len);
109
107
                break;
110
108
 
128
126
        }
129
127
}
130
128
 
131
 
/*************************************************************//**
132
 
Copies an InnoDB record to table->getInsertRecord(). */
133
 
UNIV_INTERN
 
129
/*****************************************************************
 
130
Copies an InnoDB record to table->record[0]. */
 
131
extern "C" UNIV_INTERN
134
132
void
135
133
innobase_rec_to_mysql(
136
134
/*==================*/
137
 
        Table*                  table,          /*!< in/out: MySQL table */
138
 
        const rec_t*            rec,            /*!< in: record */
139
 
        const dict_index_t*     index,          /*!< in: index */
140
 
        const ulint*            offsets)        /*!< in: rec_get_offsets(
 
135
        Table*                  table,          /* in/out: MySQL table */
 
136
        const rec_t*            rec,            /* in: record */
 
137
        const dict_index_t*     index,          /* in: index */
 
138
        const ulint*            offsets)        /* in: rec_get_offsets(
141
139
                                                rec, index, ...) */
142
140
{
143
 
        uint    n_fields        = table->getShare()->sizeFields();
 
141
        uint    n_fields        = table->s->fields;
144
142
        uint    i;
145
143
 
146
144
        ut_ad(n_fields == dict_table_get_n_user_cols(index->table));
147
145
 
148
146
        for (i = 0; i < n_fields; i++) {
149
 
                Field*          field   = table->getField(i);
 
147
                Field*          field   = table->field[i];
150
148
                ulint           ipos;
151
149
                ulint           ilen;
152
150
                const unsigned char*    ifield;
178
176
        }
179
177
}
180
178
 
181
 
/*************************************************************//**
182
 
Resets table->getInsertRecord(). */
183
 
UNIV_INTERN
 
179
/*****************************************************************
 
180
Resets table->record[0]. */
 
181
extern "C" UNIV_INTERN
184
182
void
185
183
innobase_rec_reset(
186
184
/*===============*/
187
 
        Table*                  table)          /*!< in/out: MySQL table */
 
185
        Table*                  table)          /* in/out: MySQL table */
188
186
{
189
 
        uint    n_fields        = table->getShare()->sizeFields();
 
187
        uint    n_fields        = table->s->fields;
190
188
        uint    i;
191
189
 
192
190
        for (i = 0; i < n_fields; i++) {
193
 
                table->getField(i)->set_default();
 
191
                table->field[i]->set_default();
194
192
        }
195
193
}
196
194
 
197
 
#if 0 // This is a part of the fast index code.
198
 
/******************************************************************//**
 
195
/**********************************************************************
199
196
Removes the filename encoding of a database and table name. */
200
197
static
201
198
void
202
199
innobase_convert_tablename(
203
200
/*=======================*/
204
 
        char*   s)      /*!< in: identifier; out: decoded identifier */
 
201
        char*   s)      /* in: identifier; out: decoded identifier */
205
202
{
206
203
 
207
204
        char*   slash = strchr(s, '/');
222
219
        }
223
220
}
224
221
 
225
 
 
226
 
/*******************************************************************//**
227
 
This function checks that index keys are sensible.
228
 
@return 0 or error number */
 
222
/***********************************************************************
 
223
This function checks that index keys are sensible. */
229
224
static
230
225
int
231
226
innobase_check_index_keys(
232
227
/*======================*/
233
 
        const KeyInfo*  key_info,       /*!< in: Indexes to be created */
234
 
        ulint           num_of_keys,    /*!< in: Number of indexes to
 
228
                                        /* out: 0 or error number */
 
229
        const KEY*      key_info,       /* in: Indexes to be created */
 
230
        ulint           num_of_keys)    /* in: Number of indexes to
235
231
                                        be created */
236
 
        const dict_table_t*     table)  /*!< in: Existing indexes */
237
232
{
238
233
        ulint           key_num;
239
234
 
241
236
        ut_ad(num_of_keys);
242
237
 
243
238
        for (key_num = 0; key_num < num_of_keys; key_num++) {
244
 
                const KeyInfo&  key = key_info[key_num];
 
239
                const KEY&      key = key_info[key_num];
245
240
 
246
241
                /* Check that the same index name does not appear
247
242
                twice in indexes to be created. */
248
243
 
249
244
                for (ulint i = 0; i < key_num; i++) {
250
 
                        const KeyInfo&  key2 = key_info[i];
 
245
                        const KEY&      key2 = key_info[i];
251
246
 
252
247
                        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);
 
248
                                errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: key name `%s` appears"
 
249
                                                " twice in CREATE INDEX\n",
 
250
                                                key.name);
269
251
 
270
252
                                return(ER_WRONG_NAME_FOR_INDEX);
271
253
                        }
273
255
 
274
256
                /* Check that MySQL does not try to create a column
275
257
                prefix index field on an inappropriate data type and
276
 
                that the same column does not appear twice in the index. */
 
258
                that the same colum does not appear twice in the index. */
277
259
 
278
260
                for (ulint i = 0; i < key.key_parts; i++) {
279
 
                        const KeyPartInfo&      key_part1
 
261
                        const KEY_PART_INFO&    key_part1
280
262
                                = key.key_part[i];
281
263
                        const Field*            field
282
264
                                = key_part1.field;
304
286
                                        }
305
287
                                }
306
288
 
307
 
                                my_error(ER_WRONG_KEY_COLUMN, MYF(0),
308
 
                                         field->field_name);
 
289
                                errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: MySQL is trying to"
 
290
                                                " create a column prefix"
 
291
                                                " index field on an"
 
292
                                                " inappropriate data type."
 
293
                                                " column `%s`,"
 
294
                                                " index `%s`.\n",
 
295
                                                field->field_name,
 
296
                                                key.name);
309
297
                                return(ER_WRONG_KEY_COLUMN);
310
298
                        }
311
299
 
312
300
                        for (ulint j = 0; j < i; j++) {
313
 
                                const KeyPartInfo&      key_part2
 
301
                                const KEY_PART_INFO&    key_part2
314
302
                                        = key.key_part[j];
315
303
 
316
304
                                if (strcmp(key_part1.field->field_name,
318
306
                                        continue;
319
307
                                }
320
308
 
321
 
                                my_error(ER_WRONG_KEY_COLUMN, MYF(0),
322
 
                                         key_part1.field->field_name);
 
309
                                errmsg_printf(ERRMSG_LVL_ERROR, "InnoDB: column `%s`"
 
310
                                                " is not allowed to occur"
 
311
                                                " twice in index `%s`.\n",
 
312
                                                key_part1.field->field_name,
 
313
                                                key.name);
323
314
                                return(ER_WRONG_KEY_COLUMN);
324
315
                        }
325
316
                }
328
319
        return(0);
329
320
}
330
321
 
331
 
/*******************************************************************//**
 
322
/***********************************************************************
332
323
Create index field definition for key part */
333
324
static
334
325
void
335
326
innobase_create_index_field_def(
336
327
/*============================*/
337
 
        KeyPartInfo*            key_part,       /*!< in: MySQL key definition */
338
 
        mem_heap_t*             heap,           /*!< in: memory heap */
339
 
        merge_index_field_t*    index_field)    /*!< out: index field
 
328
        KEY_PART_INFO*          key_part,       /* in: MySQL key definition */
 
329
        mem_heap_t*             heap,           /* in: memory heap */
 
330
        merge_index_field_t*    index_field)    /* out: index field
340
331
                                                definition for key_part */
341
332
{
342
333
        Field*          field;
368
359
        return;
369
360
}
370
361
 
371
 
/*******************************************************************//**
 
362
/***********************************************************************
372
363
Create index definition for key */
373
364
static
374
365
void
375
366
innobase_create_index_def(
376
367
/*======================*/
377
 
        KeyInfo*                        key,            /*!< in: key definition */
378
 
        bool                    new_primary,    /*!< in: TRUE=generating
 
368
        KEY*                    key,            /* in: key definition */
 
369
        bool                    new_primary,    /* in: TRUE=generating
379
370
                                                a new primary key
380
371
                                                on the table */
381
 
        bool                    key_primary,    /*!< in: TRUE if this key
 
372
        bool                    key_primary,    /* in: TRUE if this key
382
373
                                                is a primary key */
383
 
        merge_index_def_t*      index,          /*!< out: index definition */
384
 
        mem_heap_t*             heap)           /*!< in: heap where memory
 
374
        merge_index_def_t*      index,          /* out: index definition */
 
375
        mem_heap_t*             heap)           /* in: heap where memory
385
376
                                                is allocated */
386
377
{
387
378
        ulint   i;
420
411
        return;
421
412
}
422
413
 
423
 
/*******************************************************************//**
 
414
/***********************************************************************
424
415
Copy index field definition */
425
416
static
426
417
void
427
418
innobase_copy_index_field_def(
428
419
/*==========================*/
429
 
        const dict_field_t*     field,          /*!< in: definition to copy */
430
 
        merge_index_field_t*    index_field)    /*!< out: copied definition */
 
420
        const dict_field_t*     field,          /* in: definition to copy */
 
421
        merge_index_field_t*    index_field)    /* out: copied definition */
431
422
{
432
423
        assert(field != NULL);
433
424
        assert(index_field != NULL);
438
429
        return;
439
430
}
440
431
 
441
 
/*******************************************************************//**
 
432
/***********************************************************************
442
433
Copy index definition for the index */
443
434
static
444
435
void
445
436
innobase_copy_index_def(
446
437
/*====================*/
447
 
        const dict_index_t*     index,  /*!< in: index definition to copy */
448
 
        merge_index_def_t*      new_index,/*!< out: Index definition */
449
 
        mem_heap_t*             heap)   /*!< in: heap where allocated */
 
438
        const dict_index_t*     index,  /* in: index definition to copy */
 
439
        merge_index_def_t*      new_index,/* out: Index definition */
 
440
        mem_heap_t*             heap)   /* in: heap where allocated */
450
441
{
451
442
        ulint   n_fields;
452
443
        ulint   i;
474
465
        return;
475
466
}
476
467
 
477
 
/*******************************************************************//**
 
468
/***********************************************************************
478
469
Create an index table where indexes are ordered as follows:
479
470
 
480
471
IF a new primary key is defined for the table THEN
489
480
 
490
481
ENDIF
491
482
 
492
 
 
493
 
@return key definitions or NULL */
494
 
 
 
483
*/
495
484
static
496
485
merge_index_def_t*
497
486
innobase_create_key_def(
498
487
/*====================*/
499
 
        trx_t*          trx,            /*!< in: trx */
500
 
        const dict_table_t*table,               /*!< in: table definition */
501
 
        mem_heap_t*     heap,           /*!< in: heap where space for key
 
488
                                        /* out: key definitions or NULL */
 
489
        trx_t*          trx,            /* in: trx */
 
490
        const dict_table_t*table,               /* in: table definition */
 
491
        mem_heap_t*     heap,           /* in: heap where space for key
502
492
                                        definitions are allocated */
503
 
        KeyInfo*                key_info,       /*!< in: Indexes to be created */
504
 
        ulint&          n_keys)         /*!< in/out: Number of indexes to
 
493
        KEY*            key_info,       /* in: Indexes to be created */
 
494
        ulint&          n_keys)         /* in/out: Number of indexes to
505
495
                                        be created */
506
496
{
507
497
        ulint                   i = 0;
520
510
                                     key_info->name, "PRIMARY");
521
511
 
522
512
        /* 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. */
 
513
        columns, MySQL will treat it as a PRIMARY KEY unless the
 
514
        table already has one. */
526
515
 
527
516
        if (!new_primary && (key_info->flags & HA_NOSAME)
528
 
            && (!(key_info->flags & HA_KEY_HAS_PART_KEY_SEG))
529
517
            && row_table_got_default_clust_index(table)) {
530
 
                uint    key_part = key_info->key_parts;
 
518
                uint    key_part = key_info->key_parts;
531
519
 
532
520
                new_primary = TRUE;
533
521
 
534
522
                while (key_part--) {
535
 
                        if (key_info->key_part[key_part].null_bit == 0) {
 
523
                        if (key_info->key_part[key_part].key_type
 
524
                            & FIELDFLAG_MAYBE_NULL) {
536
525
                                new_primary = FALSE;
537
526
                                break;
538
527
                        }
581
570
        return(indexdefs);
582
571
}
583
572
 
584
 
/*******************************************************************//**
585
 
Create a temporary tablename using query id, thread id, and id
586
 
@return temporary tablename */
 
573
/***********************************************************************
 
574
Create a temporary tablename using query id, thread id, and id */
587
575
static
588
576
char*
589
577
innobase_create_temporary_tablename(
590
578
/*================================*/
591
 
        mem_heap_t*     heap,           /*!< in: memory heap */
592
 
        char            id,             /*!< in: identifier [0-9a-zA-Z] */
593
 
        const char*     table_name)     /*!< in: table name */
 
579
                                        /* out: temporary tablename */
 
580
        mem_heap_t*     heap,           /* in: memory heap */
 
581
        char            id,             /* in: identifier [0-9a-zA-Z] */
 
582
        const char*     table_name)     /* in: table name */
594
583
{
595
584
        char*                   name;
596
585
        ulint                   len;
606
595
        return(name);
607
596
}
608
597
 
609
 
 
610
 
/*******************************************************************//**
611
 
Create indexes.
612
 
@return 0 or error number */
 
598
/***********************************************************************
 
599
Create indexes. */
613
600
UNIV_INTERN
614
601
int
615
602
ha_innobase::add_index(
616
603
/*===================*/
617
 
                       Session *session,
618
 
        Table*  i_table,        /*!< in: Table where indexes are created */
619
 
        KeyInfo*        key_info,       /*!< in: Indexes to be created */
620
 
        uint    num_of_keys)    /*!< in: Number of indexes to be created */
 
604
                                /* out: 0 or error number */
 
605
        Table*  i_table,        /* in: Table where indexes are created */
 
606
        KEY*    key_info,       /* in: Indexes to be created */
 
607
        uint    num_of_keys)    /* in: Number of indexes to be created */
621
608
{
622
 
        dict_index_t**  index;          /*!< Index to be created */
623
 
        dict_table_t*   innodb_table;   /*!< InnoDB table in dictionary */
624
 
        dict_table_t*   indexed_table;  /*!< Table where indexes are created */
625
 
        merge_index_def_t* index_defs;  /*!< Index definitions */
626
 
        mem_heap_t*     heap;           /*!< Heap for index definitions */
627
 
        trx_t*          trx;            /*!< Transaction */
 
609
        dict_index_t**  index;          /* Index to be created */
 
610
        dict_table_t*   innodb_table;   /* InnoDB table in dictionary */
 
611
        dict_table_t*   indexed_table;  /* Table where indexes are created */
 
612
        merge_index_def_t* index_defs;  /* Index definitions */
 
613
        mem_heap_t*     heap;           /* Heap for index definitions */
 
614
        trx_t*          trx;            /* Transaction */
628
615
        ulint           num_of_idx;
629
616
        ulint           num_created     = 0;
630
617
        ibool           dict_locked     = FALSE;
631
618
        ulint           new_primary;
632
 
        int             error;
 
619
        ulint           error;
633
620
 
634
621
        ut_a(i_table);
635
622
        ut_a(key_info);
639
626
                return(HA_ERR_WRONG_COMMAND);
640
627
        }
641
628
 
642
 
        update_session(session);
 
629
        update_session();
643
630
 
644
631
        heap = mem_heap_create(1024);
645
632
 
646
633
        /* In case MySQL calls this in the middle of a SELECT query, release
647
634
        possible adaptive hash latch to avoid deadlocks of threads. */
648
635
        trx_search_latch_release_if_reserved(prebuilt->trx);
649
 
        trx_start_if_not_started(prebuilt->trx);
650
636
 
651
637
        /* Create a background transaction for the operations on
652
638
        the data dictionary tables. */
656
642
        innodb_table = indexed_table
657
643
                = dict_table_get(prebuilt->table->name, FALSE);
658
644
 
659
 
        if (UNIV_UNLIKELY(!innodb_table)) {
660
 
                error = HA_ERR_NO_SUCH_TABLE;
661
 
                goto err_exit;
662
 
        }
 
645
        /* Check that index keys are sensible */
663
646
 
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
 
        }
 
647
        error = innobase_check_index_keys(key_info, num_of_keys);
672
648
 
673
649
        if (UNIV_UNLIKELY(error)) {
674
650
err_exit:
675
651
                mem_heap_free(heap);
676
 
                trx_general_rollback_for_mysql(trx, NULL);
 
652
                trx_general_rollback_for_mysql(trx, FALSE, NULL);
677
653
                trx_free_for_mysql(trx);
678
654
                trx_commit_for_mysql(prebuilt->trx);
679
655
                return(error);
714
690
        row_mysql_lock_data_dictionary(trx);
715
691
        dict_locked = TRUE;
716
692
 
717
 
        ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
718
 
 
719
693
        /* If a new primary key is defined for the table we need
720
694
        to drop the original table and rebuild all indexes. */
721
695
 
748
722
                                        user_session);
749
723
                        }
750
724
 
751
 
                        ut_d(dict_table_check_for_dup_indexes(innodb_table,
752
 
                                                              FALSE));
753
725
                        row_mysql_unlock_data_dictionary(trx);
754
726
                        goto err_exit;
755
727
                }
774
746
 
775
747
        ut_ad(error == DB_SUCCESS);
776
748
 
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
749
        /* 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. */
 
750
        the table locks on the system tables.  Unfortunately, this
 
751
        means that if MySQL crashes while creating a new primary key
 
752
        inside row_merge_build_indexes(), indexed_table will not be
 
753
        dropped on crash recovery.  Thus, it will become orphaned. */
787
754
        trx_commit_for_mysql(trx);
788
755
 
789
756
        row_mysql_unlock_data_dictionary(trx);
813
780
                                        index, num_of_idx, i_table);
814
781
 
815
782
error_handling:
 
783
#ifdef UNIV_DEBUG
 
784
        /* TODO: At the moment we can't handle the following statement
 
785
        in our debugging code below:
 
786
 
 
787
        alter table t drop index b, add index (b);
 
788
 
 
789
        The fix will have to parse the SQL and note that the index
 
790
        being added has the same name as the the one being dropped and
 
791
        ignore that in the dup index check.*/
 
792
        //dict_table_check_for_dup_indexes(prebuilt->table);
 
793
#endif
816
794
 
817
795
        /* After an error, remove all those index definitions from the
818
796
        dictionary which were defined. */
825
803
                row_mysql_lock_data_dictionary(trx);
826
804
                dict_locked = TRUE;
827
805
 
828
 
                ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
829
 
 
830
806
                if (!new_primary) {
831
807
                        error = row_merge_rename_indexes(trx, indexed_table);
832
808
 
873
849
                indexed_table->n_mysql_handles_opened++;
874
850
 
875
851
                error = row_merge_drop_table(trx, innodb_table);
876
 
                innodb_table = indexed_table;
877
852
                goto convert_error;
878
853
 
879
854
        case DB_TOO_BIG_RECORD:
887
862
                prebuilt->trx->error_info = NULL;
888
863
                /* fall through */
889
864
        default:
890
 
                trx->error_state = DB_SUCCESS;
891
 
 
892
865
                if (new_primary) {
893
 
                        if (indexed_table != innodb_table) {
894
 
                                row_merge_drop_table(trx, indexed_table);
895
 
                        }
 
866
                        row_merge_drop_table(trx, indexed_table);
896
867
                } else {
897
868
                        if (!dict_locked) {
898
869
                                row_mysql_lock_data_dictionary(trx);
916
887
        }
917
888
 
918
889
        if (dict_locked) {
919
 
                ut_d(dict_table_check_for_dup_indexes(innodb_table, FALSE));
920
890
                row_mysql_unlock_data_dictionary(trx);
921
891
        }
922
892
 
928
898
        return(error);
929
899
}
930
900
 
931
 
/*******************************************************************//**
932
 
Prepare to drop some indexes of a table.
933
 
@return 0 or error number */
 
901
/***********************************************************************
 
902
Prepare to drop some indexes of a table. */
934
903
UNIV_INTERN
935
904
int
936
905
ha_innobase::prepare_drop_index(
937
906
/*============================*/
938
 
                                Session *session,
939
 
        Table*  i_table,        /*!< in: Table where indexes are dropped */
940
 
        uint*   key_num,        /*!< in: Key nums to be dropped */
941
 
        uint    num_of_keys)    /*!< in: Number of keys to be dropped */
 
907
                                /* out: 0 or error number */
 
908
        Table*  i_table,        /* in: Table where indexes are dropped */
 
909
        uint*   key_num,        /* in: Key nums to be dropped */
 
910
        uint    num_of_keys)    /* in: Number of keys to be dropped */
942
911
{
943
912
        trx_t*          trx;
944
913
        int             err = 0;
951
920
                return(HA_ERR_WRONG_COMMAND);
952
921
        }
953
922
 
954
 
        update_session(session);
 
923
        update_session();
955
924
 
956
925
        trx_search_latch_release_if_reserved(prebuilt->trx);
957
926
        trx = prebuilt->trx;
959
928
        /* Test and mark all the indexes to be dropped */
960
929
 
961
930
        row_mysql_lock_data_dictionary(trx);
962
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
963
931
 
964
932
        /* Check that none of the indexes have previously been flagged
965
933
        for deletion. */
973
941
        }
974
942
 
975
943
        for (n_key = 0; n_key < num_of_keys; n_key++) {
976
 
                const KeyInfo*  key;
 
944
                const KEY*      key;
977
945
                dict_index_t*   index;
978
946
 
979
947
                key = i_table->key_info + key_num[n_key];
993
961
 
994
962
                /* Refuse to drop the clustered index.  It would be
995
963
                better to automatically generate a clustered index,
996
 
                but drizzled::alter_table() will call this method only
 
964
                but mysql_alter_table() will call this method only
997
965
                after ha_innobase::add_index(). */
998
966
 
999
967
                if (dict_index_is_clust(index)) {
1005
973
                index->to_be_dropped = TRUE;
1006
974
        }
1007
975
 
1008
 
        /* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined
 
976
        /* If FOREIGN_KEY_CHECK = 1 you may not drop an index defined
1009
977
        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.
 
978
        tables contain indexes for the constraint.  Note that CREATE
 
979
        INDEX id ON table does a CREATE INDEX and DROP INDEX, and we
 
980
        can ignore here foreign keys because a new index for the
 
981
        foreign key has already been created.
1015
982
 
1016
983
        We check for the foreign key constraints after marking the
1017
984
        candidate indexes for deletion, because when we check for an
1126
1093
                } while (index);
1127
1094
        }
1128
1095
 
1129
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1130
1096
        row_mysql_unlock_data_dictionary(trx);
1131
1097
 
1132
1098
        return(err);
1133
1099
}
1134
1100
 
1135
 
/*******************************************************************//**
1136
 
Drop the indexes that were passed to a successful prepare_drop_index().
1137
 
@return 0 or error number */
 
1101
/***********************************************************************
 
1102
Drop the indexes that were passed to a successful prepare_drop_index(). */
1138
1103
UNIV_INTERN
1139
1104
int
1140
1105
ha_innobase::final_drop_index(
1141
1106
/*==========================*/
1142
 
                              Session *session,
1143
 
        Table*  )               /*!< in: Table where indexes are dropped */
 
1107
                                /* out: 0 or error number */
 
1108
        Table*          )       /* in: Table where indexes are dropped */
1144
1109
{
1145
 
        dict_index_t*   index;          /*!< Index to be dropped */
1146
 
        trx_t*          trx;            /*!< Transaction */
 
1110
        dict_index_t*   index;          /* Index to be dropped */
 
1111
        trx_t*          trx;            /* Transaction */
1147
1112
        int             err;
1148
1113
 
1149
1114
        if (srv_created_new_raw || srv_force_recovery) {
1150
1115
                return(HA_ERR_WRONG_COMMAND);
1151
1116
        }
1152
1117
 
1153
 
        update_session(session);
 
1118
        update_session();
1154
1119
 
1155
1120
        trx_search_latch_release_if_reserved(prebuilt->trx);
1156
 
        trx_start_if_not_started(prebuilt->trx);
1157
1121
 
1158
1122
        /* Create a background transaction for the operations on
1159
1123
        the data dictionary tables. */
1171
1135
                prebuilt->table->flags, user_session);
1172
1136
 
1173
1137
        row_mysql_lock_data_dictionary(trx);
1174
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1175
1138
 
1176
1139
        if (UNIV_UNLIKELY(err)) {
1177
1140
 
1208
1171
                ut_a(!index->to_be_dropped);
1209
1172
        }
1210
1173
 
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;
 
1174
#ifdef UNIV_DEBUG
 
1175
        dict_table_check_for_dup_indexes(prebuilt->table);
 
1176
#endif
1214
1177
 
1215
1178
func_exit:
1216
 
        ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
1217
1179
        trx_commit_for_mysql(trx);
1218
1180
        trx_commit_for_mysql(prebuilt->trx);
1219
1181
        row_mysql_unlock_data_dictionary(trx);
1233
1195
 
1234
1196
        return(err);
1235
1197
}
1236
 
#endif