~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-09-27 21:52:36 UTC
  • mfrom: (1138.1.1 build)
  • Revision ID: brian@gaz-20090927215236-5nx5q6u1ub8uf0l6
Merge Monty (fix for distcheck)

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