~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2004 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/* drop and alter of tables */
17
18
#include "mysql_priv.h"
19
#include <hash.h>
20
#include <myisam.h>
21
#include <my_dir.h>
22
#include "sql_show.h"
23
24
int creating_table= 0;        // How many mysql_create_table are running
25
26
const char *primary_key_name="PRIMARY";
27
28
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
30
static int copy_data_between_tables(TABLE *from,TABLE *to,
31
                                    List<Create_field> &create, bool ignore,
32
                                    uint order_num, ORDER *order,
33
                                    ha_rows *copied,ha_rows *deleted,
34
                                    enum enum_enable_or_disable keys_onoff,
35
                                    bool error_if_not_empty);
36
37
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
38
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
39
static int
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
41
                           Alter_info *alter_info,
42
                           bool tmp_table,
43
                               uint *db_options,
44
                               handler *file, KEY **key_info_buffer,
45
                               uint *key_count, int select_field_count);
46
static bool
47
mysql_prepare_alter_table(THD *thd, TABLE *table,
48
                          HA_CREATE_INFO *create_info,
49
                          Alter_info *alter_info);
50
51
#ifndef DBUG_OFF
52
53
/* Wait until we get a 'mysql_kill' signal */
54
55
static void wait_for_kill_signal(THD *thd)
56
{
57
  while (thd->killed == 0)
58
    sleep(1);
59
  // Reset signal and continue as if nothing happend
60
  thd->killed= THD::NOT_KILLED;
61
}
62
#endif
63
64
65
/*
66
  Translate a file name to a table name (WL #1324).
67
68
  SYNOPSIS
69
    filename_to_tablename()
70
      from                      The file name in my_charset_filename.
71
      to                OUT     The table name in system_charset_info.
72
      to_length                 The size of the table name buffer.
73
74
  RETURN
75
    Table name length.
76
*/
77
78
uint filename_to_tablename(const char *from, char *to, uint to_length)
79
{
80
  uint errors;
81
  uint res;
82
  DBUG_ENTER("filename_to_tablename");
83
  DBUG_PRINT("enter", ("from '%s'", from));
84
85
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
86
  {
87
    /* Temporary table name. */
88
    res= (strnmov(to, from, to_length) - to);
89
  }
90
  else
91
  {
92
    res= strconvert(&my_charset_filename, from,
93
                    system_charset_info,  to, to_length, &errors);
94
    if (errors) // Old 5.0 name
95
    {
96
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
97
            to);
98
      sql_print_error("Invalid (old?) table or database name '%s'", from);
99
      /*
100
        TODO: add a stored procedure for fix table and database names,
101
        and mention its name in error log.
102
      */
103
    }
104
  }
105
106
  DBUG_PRINT("exit", ("to '%s'", to));
107
  DBUG_RETURN(res);
108
}
109
110
111
/*
112
  Translate a table name to a file name (WL #1324).
113
114
  SYNOPSIS
115
    tablename_to_filename()
116
      from                      The table name in system_charset_info.
117
      to                OUT     The file name in my_charset_filename.
118
      to_length                 The size of the file name buffer.
119
120
  RETURN
121
    File name length.
122
*/
123
124
uint tablename_to_filename(const char *from, char *to, uint to_length)
125
{
126
  uint errors, length;
127
  DBUG_ENTER("tablename_to_filename");
128
  DBUG_PRINT("enter", ("from '%s'", from));
129
130
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
131
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
132
    DBUG_RETURN((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
133
                                to_length-1) -
134
                        (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
135
  length= strconvert(system_charset_info, from,
136
                     &my_charset_filename, to, to_length, &errors);
137
  if (check_if_legal_tablename(to) &&
138
      length + 4 < to_length)
139
  {
140
    memcpy(to + length, "@@@", 4);
141
    length+= 3;
142
  }
143
  DBUG_PRINT("exit", ("to '%s'", to));
144
  DBUG_RETURN(length);
145
}
146
147
148
/*
149
  Creates path to a file: mysql_data_dir/db/table.ext
150
151
  SYNOPSIS
152
   build_table_filename()
153
     buff                       Where to write result in my_charset_filename.
154
                                This may be the same as table_name.
155
     bufflen                    buff size
156
     db                         Database name in system_charset_info.
157
     table_name                 Table name in system_charset_info.
158
     ext                        File extension.
159
     flags                      FN_FROM_IS_TMP or FN_TO_IS_TMP or FN_IS_TMP
160
                                table_name is temporary, do not change.
161
162
  NOTES
163
164
    Uses database and table name, and extension to create
165
    a file name in mysql_data_dir. Database and table
166
    names are converted from system_charset_info into "fscs".
167
    Unless flags indicate a temporary table name.
168
    'db' is always converted.
169
    'ext' is not converted.
170
171
    The conversion suppression is required for ALTER TABLE. This
172
    statement creates intermediate tables. These are regular
173
    (non-temporary) tables with a temporary name. Their path names must
174
    be derivable from the table name. So we cannot use
175
    build_tmptable_filename() for them.
176
177
  RETURN
178
    path length
179
*/
180
181
uint build_table_filename(char *buff, size_t bufflen, const char *db,
182
                          const char *table_name, const char *ext, uint flags)
183
{
184
  char dbbuff[FN_REFLEN];
185
  char tbbuff[FN_REFLEN];
186
  DBUG_ENTER("build_table_filename");
187
  DBUG_PRINT("enter", ("db: '%s'  table_name: '%s'  ext: '%s'  flags: %x",
188
                       db, table_name, ext, flags));
189
190
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
191
    strnmov(tbbuff, table_name, sizeof(tbbuff));
192
  else
193
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
194
195
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
196
197
  char *end = buff + bufflen;
198
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
199
  char *pos = strnmov(buff, mysql_data_home, bufflen);
200
  int rootdir_len= strlen(FN_ROOTDIR);
201
  if (pos - rootdir_len >= buff &&
202
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
203
    pos= strnmov(pos, FN_ROOTDIR, end - pos);
204
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
205
#ifdef USE_SYMDIR
206
  unpack_dirname(buff, buff);
207
  pos= strend(buff);
208
#endif
209
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
210
211
  DBUG_PRINT("exit", ("buff: '%s'", buff));
212
  DBUG_RETURN(pos - buff);
213
}
214
215
216
/*
217
  Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
218
219
  SYNOPSIS
220
   build_tmptable_filename()
221
     thd                        The thread handle.
222
     buff                       Where to write result in my_charset_filename.
223
     bufflen                    buff size
224
225
  NOTES
226
227
    Uses current_pid, thread_id, and tmp_table counter to create
228
    a file name in mysql_tmpdir.
229
230
  RETURN
231
    path length
232
*/
233
234
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
235
{
236
  DBUG_ENTER("build_tmptable_filename");
237
238
  char *p= strnmov(buff, mysql_tmpdir, bufflen);
239
  my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
240
	      tmp_file_prefix, current_pid,
241
              thd->thread_id, thd->tmp_table++, reg_ext);
242
243
  if (lower_case_table_names)
244
  {
245
    /* Convert all except tmpdir to lower case */
246
    my_casedn_str(files_charset_info, p);
247
  }
248
249
  uint length= unpack_filename(buff, buff);
250
  DBUG_PRINT("exit", ("buff: '%s'", buff));
251
  DBUG_RETURN(length);
252
}
253
254
/*
255
--------------------------------------------------------------------------
256
257
   MODULE: DDL log
258
   -----------------
259
260
   This module is used to ensure that we can recover from crashes that occur
261
   in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
262
   We need to ensure that both t1 and t2 are dropped and not only t1 and
263
   also that each table drop is entirely done and not "half-baked".
264
265
   To support this we create log entries for each meta-data statement in the
266
   ddl log while we are executing. These entries are dropped when the
267
   operation is completed.
268
269
   At recovery those entries that were not completed will be executed.
270
271
   There is only one ddl log in the system and it is protected by a mutex
272
   and there is a global struct that contains information about its current
273
   state.
274
275
   History:
276
   First version written in 2006 by Mikael Ronstrom
277
--------------------------------------------------------------------------
278
*/
279
280
281
struct st_global_ddl_log
282
{
283
  /*
284
    We need to adjust buffer size to be able to handle downgrades/upgrades
285
    where IO_SIZE has changed. We'll set the buffer size such that we can
286
    handle that the buffer size was upto 4 times bigger in the version
287
    that wrote the DDL log.
288
  */
289
  char file_entry_buf[4*IO_SIZE];
290
  char file_name_str[FN_REFLEN];
291
  char *file_name;
292
  DDL_LOG_MEMORY_ENTRY *first_free;
293
  DDL_LOG_MEMORY_ENTRY *first_used;
294
  uint num_entries;
295
  File file_id;
296
  uint name_len;
297
  uint io_size;
298
  bool inited;
299
  bool do_release;
300
  bool recovery_phase;
301
  st_global_ddl_log() : inited(false), do_release(false) {}
302
};
303
304
st_global_ddl_log global_ddl_log;
305
306
pthread_mutex_t LOCK_gdl;
307
308
#define DDL_LOG_ENTRY_TYPE_POS 0
309
#define DDL_LOG_ACTION_TYPE_POS 1
310
#define DDL_LOG_PHASE_POS 2
311
#define DDL_LOG_NEXT_ENTRY_POS 4
312
#define DDL_LOG_NAME_POS 8
313
314
#define DDL_LOG_NUM_ENTRY_POS 0
315
#define DDL_LOG_NAME_LEN_POS 4
316
#define DDL_LOG_IO_SIZE_POS 8
317
318
/*
319
  Read one entry from ddl log file
320
  SYNOPSIS
321
    read_ddl_log_file_entry()
322
    entry_no                     Entry number to read
323
  RETURN VALUES
324
    TRUE                         Error
325
    FALSE                        Success
326
*/
327
328
static bool read_ddl_log_file_entry(uint entry_no)
329
{
330
  bool error= FALSE;
331
  File file_id= global_ddl_log.file_id;
332
  uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
333
  uint io_size= global_ddl_log.io_size;
334
  DBUG_ENTER("read_ddl_log_file_entry");
335
31 by Brian Aker
Removed my versions of pread/pwrite from the Kernel
336
  if (pread(file_id, file_entry_buf, io_size, io_size * entry_no) != io_size)
1 by brian
clean slate
337
    error= TRUE;
338
  DBUG_RETURN(error);
339
}
340
341
342
/*
343
  Write one entry from ddl log file
344
  SYNOPSIS
345
    write_ddl_log_file_entry()
346
    entry_no                     Entry number to read
347
  RETURN VALUES
348
    TRUE                         Error
349
    FALSE                        Success
350
*/
351
352
static bool write_ddl_log_file_entry(uint entry_no)
353
{
354
  bool error= FALSE;
355
  File file_id= global_ddl_log.file_id;
356
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
357
  DBUG_ENTER("write_ddl_log_file_entry");
358
31 by Brian Aker
Removed my versions of pread/pwrite from the Kernel
359
  if (pwrite(file_id, (uchar*)file_entry_buf,
360
             IO_SIZE, IO_SIZE * entry_no) != IO_SIZE)
1 by brian
clean slate
361
    error= TRUE;
362
  DBUG_RETURN(error);
363
}
364
365
366
/*
367
  Write ddl log header
368
  SYNOPSIS
369
    write_ddl_log_header()
370
  RETURN VALUES
371
    TRUE                      Error
372
    FALSE                     Success
373
*/
374
375
static bool write_ddl_log_header()
376
{
377
  uint16 const_var;
378
  bool error= FALSE;
379
  DBUG_ENTER("write_ddl_log_header");
380
381
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
382
            global_ddl_log.num_entries);
383
  const_var= FN_LEN;
384
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
385
            (ulong) const_var);
386
  const_var= IO_SIZE;
387
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
388
            (ulong) const_var);
389
  if (write_ddl_log_file_entry(0UL))
390
  {
391
    sql_print_error("Error writing ddl log header");
392
    DBUG_RETURN(TRUE);
393
  }
394
  VOID(sync_ddl_log());
395
  DBUG_RETURN(error);
396
}
397
398
399
/*
400
  Create ddl log file name
401
  SYNOPSIS
402
    create_ddl_log_file_name()
403
    file_name                   Filename setup
404
  RETURN VALUES
405
    NONE
406
*/
407
408
static inline void create_ddl_log_file_name(char *file_name)
409
{
410
  strxmov(file_name, mysql_data_home, "/", "ddl_log.log", NullS);
411
}
412
413
414
/*
415
  Read header of ddl log file
416
  SYNOPSIS
417
    read_ddl_log_header()
418
  RETURN VALUES
419
    > 0                  Last entry in ddl log
420
    0                    No entries in ddl log
421
  DESCRIPTION
422
    When we read the ddl log header we get information about maximum sizes
423
    of names in the ddl log and we also get information about the number
424
    of entries in the ddl log.
425
*/
426
427
static uint read_ddl_log_header()
428
{
429
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
430
  char file_name[FN_REFLEN];
431
  uint entry_no;
432
  bool successful_open= FALSE;
433
  DBUG_ENTER("read_ddl_log_header");
434
435
  create_ddl_log_file_name(file_name);
436
  if ((global_ddl_log.file_id= my_open(file_name,
437
                                        O_RDWR | O_BINARY, MYF(0))) >= 0)
438
  {
439
    if (read_ddl_log_file_entry(0UL))
440
    {
441
      /* Write message into error log */
442
      sql_print_error("Failed to read ddl log file in recovery");
443
    }
444
    else
445
      successful_open= TRUE;
446
  }
447
  entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
448
  global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
449
  if (successful_open)
450
  {
451
    global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
452
    DBUG_ASSERT(global_ddl_log.io_size <=
453
                sizeof(global_ddl_log.file_entry_buf));
454
  }
455
  else
456
  {
457
    entry_no= 0;
458
  }
459
  global_ddl_log.first_free= NULL;
460
  global_ddl_log.first_used= NULL;
461
  global_ddl_log.num_entries= 0;
462
  VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
463
  global_ddl_log.do_release= true;
464
  DBUG_RETURN(entry_no);
465
}
466
467
468
/*
469
  Read a ddl log entry
470
  SYNOPSIS
471
    read_ddl_log_entry()
472
    read_entry               Number of entry to read
473
    out:entry_info           Information from entry
474
  RETURN VALUES
475
    TRUE                     Error
476
    FALSE                    Success
477
  DESCRIPTION
478
    Read a specified entry in the ddl log
479
*/
480
481
bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
482
{
483
  char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
484
  uint inx;
485
  uchar single_char;
486
  DBUG_ENTER("read_ddl_log_entry");
487
488
  if (read_ddl_log_file_entry(read_entry))
489
  {
490
    DBUG_RETURN(TRUE);
491
  }
492
  ddl_log_entry->entry_pos= read_entry;
493
  single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
494
  ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
495
  single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
496
  ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
497
  ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
498
  ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
499
  ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
500
  inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
501
  ddl_log_entry->from_name= &file_entry_buf[inx];
502
  inx+= global_ddl_log.name_len;
503
  ddl_log_entry->handler_name= &file_entry_buf[inx];
504
  DBUG_RETURN(FALSE);
505
}
506
507
508
/*
509
  Initialise ddl log
510
  SYNOPSIS
511
    init_ddl_log()
512
513
  DESCRIPTION
514
    Write the header of the ddl log file and length of names. Also set
515
    number of entries to zero.
516
517
  RETURN VALUES
518
    TRUE                     Error
519
    FALSE                    Success
520
*/
521
522
static bool init_ddl_log()
523
{
524
  char file_name[FN_REFLEN];
525
  DBUG_ENTER("init_ddl_log");
526
527
  if (global_ddl_log.inited)
528
    goto end;
529
530
  global_ddl_log.io_size= IO_SIZE;
531
  create_ddl_log_file_name(file_name);
532
  if ((global_ddl_log.file_id= my_create(file_name,
533
                                         CREATE_MODE,
534
                                         O_RDWR | O_TRUNC | O_BINARY,
535
                                         MYF(MY_WME))) < 0)
536
  {
537
    /* Couldn't create ddl log file, this is serious error */
538
    sql_print_error("Failed to open ddl log file");
539
    DBUG_RETURN(TRUE);
540
  }
541
  global_ddl_log.inited= TRUE;
542
  if (write_ddl_log_header())
543
  {
544
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
545
    global_ddl_log.inited= FALSE;
546
    DBUG_RETURN(TRUE);
547
  }
548
549
end:
550
  DBUG_RETURN(FALSE);
551
}
552
553
554
/*
555
  Execute one action in a ddl log entry
556
  SYNOPSIS
557
    execute_ddl_log_action()
558
    ddl_log_entry              Information in action entry to execute
559
  RETURN VALUES
560
    TRUE                       Error
561
    FALSE                      Success
562
*/
563
564
static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
565
{
566
  bool frm_action= FALSE;
567
  LEX_STRING handler_name;
568
  handler *file= NULL;
569
  MEM_ROOT mem_root;
570
  int error= TRUE;
571
  char to_path[FN_REFLEN];
572
  char from_path[FN_REFLEN];
573
  handlerton *hton;
574
  DBUG_ENTER("execute_ddl_log_action");
575
576
  if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
577
  {
578
    DBUG_RETURN(FALSE);
579
  }
580
  handler_name.str= (char*)ddl_log_entry->handler_name;
581
  handler_name.length= strlen(ddl_log_entry->handler_name);
582
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 
583
  if (!strcmp(ddl_log_entry->handler_name, reg_ext))
584
    frm_action= TRUE;
585
  else
586
  {
587
    plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
588
    if (!plugin)
589
    {
590
      my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
591
      goto error;
592
    }
593
    hton= plugin_data(plugin, handlerton*);
594
    file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
595
    if (!file)
596
    {
597
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
598
      goto error;
599
    }
600
  }
601
  switch (ddl_log_entry->action_type)
602
  {
603
    case DDL_LOG_REPLACE_ACTION:
604
    case DDL_LOG_DELETE_ACTION:
605
    {
606
      if (ddl_log_entry->phase == 0)
607
      {
608
        if (frm_action)
609
        {
610
          strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
611
          if ((error= my_delete(to_path, MYF(MY_WME))))
612
          {
613
            if (my_errno != ENOENT)
614
              break;
615
          }
616
        }
617
        else
618
        {
619
          if ((error= file->ha_delete_table(ddl_log_entry->name)))
620
          {
621
            if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
622
              break;
623
          }
624
        }
625
        if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
626
          break;
627
        VOID(sync_ddl_log());
628
        error= FALSE;
629
        if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
630
          break;
631
      }
632
      DBUG_ASSERT(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
633
      /*
634
        Fall through and perform the rename action of the replace
635
        action. We have already indicated the success of the delete
636
        action in the log entry by stepping up the phase.
637
      */
638
    }
639
    case DDL_LOG_RENAME_ACTION:
640
    {
641
      error= TRUE;
642
      if (frm_action)
643
      {
644
        strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
645
        strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
646
        if (my_rename(from_path, to_path, MYF(MY_WME)))
647
          break;
648
      }
649
      else
650
      {
651
        if (file->ha_rename_table(ddl_log_entry->from_name,
652
                                  ddl_log_entry->name))
653
          break;
654
      }
655
      if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
656
        break;
657
      VOID(sync_ddl_log());
658
      error= FALSE;
659
      break;
660
    }
661
    default:
662
      DBUG_ASSERT(0);
663
      break;
664
  }
665
  delete file;
666
error:
667
  free_root(&mem_root, MYF(0)); 
668
  DBUG_RETURN(error);
669
}
670
671
672
/*
673
  Get a free entry in the ddl log
674
  SYNOPSIS
675
    get_free_ddl_log_entry()
676
    out:active_entry                A ddl log memory entry returned
677
  RETURN VALUES
678
    TRUE                       Error
679
    FALSE                      Success
680
*/
681
682
static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
683
                                   bool *write_header)
684
{
685
  DDL_LOG_MEMORY_ENTRY *used_entry;
686
  DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
687
  DBUG_ENTER("get_free_ddl_log_entry");
688
689
  if (global_ddl_log.first_free == NULL)
690
  {
691
    if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
692
                              sizeof(DDL_LOG_MEMORY_ENTRY), MYF(MY_WME))))
693
    {
694
      sql_print_error("Failed to allocate memory for ddl log free list");
695
      DBUG_RETURN(TRUE);
696
    }
697
    global_ddl_log.num_entries++;
698
    used_entry->entry_pos= global_ddl_log.num_entries;
699
    *write_header= TRUE;
700
  }
701
  else
702
  {
703
    used_entry= global_ddl_log.first_free;
704
    global_ddl_log.first_free= used_entry->next_log_entry;
705
    *write_header= FALSE;
706
  }
707
  /*
708
    Move from free list to used list
709
  */
710
  used_entry->next_log_entry= first_used;
711
  used_entry->prev_log_entry= NULL;
712
  global_ddl_log.first_used= used_entry;
713
  if (first_used)
714
    first_used->prev_log_entry= used_entry;
715
716
  *active_entry= used_entry;
717
  DBUG_RETURN(FALSE);
718
}
719
720
721
/*
722
  External interface methods for the DDL log Module
723
  ---------------------------------------------------
724
*/
725
726
/*
727
  SYNOPSIS
728
    write_ddl_log_entry()
729
    ddl_log_entry         Information about log entry
730
    out:entry_written     Entry information written into   
731
732
  RETURN VALUES
733
    TRUE                      Error
734
    FALSE                     Success
735
736
  DESCRIPTION
737
    A careful write of the ddl log is performed to ensure that we can
738
    handle crashes occurring during CREATE and ALTER TABLE processing.
739
*/
740
741
bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
742
                         DDL_LOG_MEMORY_ENTRY **active_entry)
743
{
744
  bool error, write_header;
745
  DBUG_ENTER("write_ddl_log_entry");
746
747
  if (init_ddl_log())
748
  {
749
    DBUG_RETURN(TRUE);
750
  }
751
  global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
752
                                    (char)DDL_LOG_ENTRY_CODE;
753
  global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
754
                                    (char)ddl_log_entry->action_type;
755
  global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
756
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
757
            ddl_log_entry->next_entry);
758
  DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_LEN);
759
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
760
          ddl_log_entry->name, FN_LEN - 1);
761
  if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
762
      ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
763
  {
764
    DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_LEN);
765
    strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
766
          ddl_log_entry->from_name, FN_LEN - 1);
767
  }
768
  else
769
    global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
770
  DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_LEN);
771
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
772
          ddl_log_entry->handler_name, FN_LEN - 1);
773
  if (get_free_ddl_log_entry(active_entry, &write_header))
774
  {
775
    DBUG_RETURN(TRUE);
776
  }
777
  error= FALSE;
778
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
779
  {
780
    error= TRUE;
781
    sql_print_error("Failed to write entry_no = %u",
782
                    (*active_entry)->entry_pos);
783
  }
784
  if (write_header && !error)
785
  {
786
    VOID(sync_ddl_log());
787
    if (write_ddl_log_header())
788
      error= TRUE;
789
  }
790
  if (error)
791
    release_ddl_log_memory_entry(*active_entry);
792
  DBUG_RETURN(error);
793
}
794
795
796
/*
797
  Write final entry in the ddl log
798
  SYNOPSIS
799
    write_execute_ddl_log_entry()
800
    first_entry                    First entry in linked list of entries
801
                                   to execute, if 0 = NULL it means that
802
                                   the entry is removed and the entries
803
                                   are put into the free list.
804
    complete                       Flag indicating we are simply writing
805
                                   info about that entry has been completed
806
    in:out:active_entry            Entry to execute, 0 = NULL if the entry
807
                                   is written first time and needs to be
808
                                   returned. In this case the entry written
809
                                   is returned in this parameter
810
  RETURN VALUES
811
    TRUE                           Error
812
    FALSE                          Success
813
814
  DESCRIPTION
815
    This is the last write in the ddl log. The previous log entries have
816
    already been written but not yet synched to disk.
817
    We write a couple of log entries that describes action to perform.
818
    This entries are set-up in a linked list, however only when a first
819
    execute entry is put as the first entry these will be executed.
820
    This routine writes this first 
821
*/ 
822
823
bool write_execute_ddl_log_entry(uint first_entry,
824
                                 bool complete,
825
                                 DDL_LOG_MEMORY_ENTRY **active_entry)
826
{
827
  bool write_header= FALSE;
828
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
829
  DBUG_ENTER("write_execute_ddl_log_entry");
830
831
  if (init_ddl_log())
832
  {
833
    DBUG_RETURN(TRUE);
834
  }
835
  if (!complete)
836
  {
837
    /*
838
      We haven't synched the log entries yet, we synch them now before
839
      writing the execute entry. If complete is true we haven't written
840
      any log entries before, we are only here to write the execute
841
      entry to indicate it is done.
842
    */
843
    VOID(sync_ddl_log());
844
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
845
  }
846
  else
847
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
848
  file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
849
  file_entry_buf[DDL_LOG_PHASE_POS]= 0;
850
  int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
851
  file_entry_buf[DDL_LOG_NAME_POS]= 0;
852
  file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
853
  file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
854
  if (!(*active_entry))
855
  {
856
    if (get_free_ddl_log_entry(active_entry, &write_header))
857
    {
858
      DBUG_RETURN(TRUE);
859
    }
860
  }
861
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
862
  {
863
    sql_print_error("Error writing execute entry in ddl log");
864
    release_ddl_log_memory_entry(*active_entry);
865
    DBUG_RETURN(TRUE);
866
  }
867
  VOID(sync_ddl_log());
868
  if (write_header)
869
  {
870
    if (write_ddl_log_header())
871
    {
872
      release_ddl_log_memory_entry(*active_entry);
873
      DBUG_RETURN(TRUE);
874
    }
875
  }
876
  DBUG_RETURN(FALSE);
877
}
878
879
880
/*
881
  For complex rename operations we need to deactivate individual entries.
882
  SYNOPSIS
883
    deactivate_ddl_log_entry()
884
    entry_no                      Entry position of record to change
885
  RETURN VALUES
886
    TRUE                         Error
887
    FALSE                        Success
888
  DESCRIPTION
889
    During replace operations where we start with an existing table called
890
    t1 and a replacement table called t1#temp or something else and where
891
    we want to delete t1 and rename t1#temp to t1 this is not possible to
892
    do in a safe manner unless the ddl log is informed of the phases in
893
    the change.
894
895
    Delete actions are 1-phase actions that can be ignored immediately after
896
    being executed.
897
    Rename actions from x to y is also a 1-phase action since there is no
898
    interaction with any other handlers named x and y.
899
    Replace action where drop y and x -> y happens needs to be a two-phase
900
    action. Thus the first phase will drop y and the second phase will
901
    rename x -> y.
902
*/
903
904
bool deactivate_ddl_log_entry(uint entry_no)
905
{
906
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
907
  DBUG_ENTER("deactivate_ddl_log_entry");
908
909
  if (!read_ddl_log_file_entry(entry_no))
910
  {
911
    if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
912
    {
913
      if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
914
          file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
915
          (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
916
           file_entry_buf[DDL_LOG_PHASE_POS] == 1))
917
        file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
918
      else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
919
      {
920
        DBUG_ASSERT(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
921
        file_entry_buf[DDL_LOG_PHASE_POS]= 1;
922
      }
923
      else
924
      {
925
        DBUG_ASSERT(0);
926
      }
927
      if (write_ddl_log_file_entry(entry_no))
928
      {
929
        sql_print_error("Error in deactivating log entry. Position = %u",
930
                        entry_no);
931
        DBUG_RETURN(TRUE);
932
      }
933
    }
934
  }
935
  else
936
  {
937
    sql_print_error("Failed in reading entry before deactivating it");
938
    DBUG_RETURN(TRUE);
939
  }
940
  DBUG_RETURN(FALSE);
941
}
942
943
944
/*
945
  Sync ddl log file
946
  SYNOPSIS
947
    sync_ddl_log()
948
  RETURN VALUES
949
    TRUE                      Error
950
    FALSE                     Success
951
*/
952
953
bool sync_ddl_log()
954
{
955
  bool error= FALSE;
956
  DBUG_ENTER("sync_ddl_log");
957
958
  if ((!global_ddl_log.recovery_phase) &&
959
      init_ddl_log())
960
  {
961
    DBUG_RETURN(TRUE);
962
  }
963
  if (my_sync(global_ddl_log.file_id, MYF(0)))
964
  {
965
    /* Write to error log */
966
    sql_print_error("Failed to sync ddl log");
967
    error= TRUE;
968
  }
969
  DBUG_RETURN(error);
970
}
971
972
973
/*
974
  Release a log memory entry
975
  SYNOPSIS
976
    release_ddl_log_memory_entry()
977
    log_memory_entry                Log memory entry to release
978
  RETURN VALUES
979
    NONE
980
*/
981
982
void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
983
{
984
  DDL_LOG_MEMORY_ENTRY *first_free= global_ddl_log.first_free;
985
  DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
986
  DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
987
  DBUG_ENTER("release_ddl_log_memory_entry");
988
989
  global_ddl_log.first_free= log_entry;
990
  log_entry->next_log_entry= first_free;
991
992
  if (prev_log_entry)
993
    prev_log_entry->next_log_entry= next_log_entry;
994
  else
995
    global_ddl_log.first_used= next_log_entry;
996
  if (next_log_entry)
997
    next_log_entry->prev_log_entry= prev_log_entry;
998
  DBUG_VOID_RETURN;
999
}
1000
1001
1002
/*
1003
  Execute one entry in the ddl log. Executing an entry means executing
1004
  a linked list of actions.
1005
  SYNOPSIS
1006
    execute_ddl_log_entry()
1007
    first_entry                Reference to first action in entry
1008
  RETURN VALUES
1009
    TRUE                       Error
1010
    FALSE                      Success
1011
*/
1012
1013
bool execute_ddl_log_entry(THD *thd, uint first_entry)
1014
{
1015
  DDL_LOG_ENTRY ddl_log_entry;
1016
  uint read_entry= first_entry;
1017
  DBUG_ENTER("execute_ddl_log_entry");
1018
1019
  pthread_mutex_lock(&LOCK_gdl);
1020
  do
1021
  {
1022
    if (read_ddl_log_entry(read_entry, &ddl_log_entry))
1023
    {
1024
      /* Write to error log and continue with next log entry */
1025
      sql_print_error("Failed to read entry = %u from ddl log",
1026
                      read_entry);
1027
      break;
1028
    }
1029
    DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
1030
                ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
1031
1032
    if (execute_ddl_log_action(thd, &ddl_log_entry))
1033
    {
1034
      /* Write to error log and continue with next log entry */
1035
      sql_print_error("Failed to execute action for entry = %u from ddl log",
1036
                      read_entry);
1037
      break;
1038
    }
1039
    read_entry= ddl_log_entry.next_entry;
1040
  } while (read_entry);
1041
  pthread_mutex_unlock(&LOCK_gdl);
1042
  DBUG_RETURN(FALSE);
1043
}
1044
1045
1046
/*
1047
  Close the ddl log
1048
  SYNOPSIS
1049
    close_ddl_log()
1050
  RETURN VALUES
1051
    NONE
1052
*/
1053
1054
static void close_ddl_log()
1055
{
1056
  DBUG_ENTER("close_ddl_log");
1057
  if (global_ddl_log.file_id >= 0)
1058
  {
1059
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
1060
    global_ddl_log.file_id= (File) -1;
1061
  }
1062
  DBUG_VOID_RETURN;
1063
}
1064
1065
1066
/*
1067
  Execute the ddl log at recovery of MySQL Server
1068
  SYNOPSIS
1069
    execute_ddl_log_recovery()
1070
  RETURN VALUES
1071
    NONE
1072
*/
1073
1074
void execute_ddl_log_recovery()
1075
{
1076
  uint num_entries, i;
1077
  THD *thd;
1078
  DDL_LOG_ENTRY ddl_log_entry;
1079
  char file_name[FN_REFLEN];
1080
  DBUG_ENTER("execute_ddl_log_recovery");
1081
1082
  /*
1083
    Initialise global_ddl_log struct
1084
  */
1085
  bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
1086
  global_ddl_log.inited= FALSE;
1087
  global_ddl_log.recovery_phase= TRUE;
1088
  global_ddl_log.io_size= IO_SIZE;
1089
  global_ddl_log.file_id= (File) -1;
1090
1091
  /*
1092
    To be able to run this from boot, we allocate a temporary THD
1093
  */
1094
  if (!(thd=new THD))
1095
    DBUG_VOID_RETURN;
1096
  thd->thread_stack= (char*) &thd;
1097
  thd->store_globals();
1098
1099
  num_entries= read_ddl_log_header();
1100
  for (i= 1; i < num_entries + 1; i++)
1101
  {
1102
    if (read_ddl_log_entry(i, &ddl_log_entry))
1103
    {
1104
      sql_print_error("Failed to read entry no = %u from ddl log",
1105
                       i);
1106
      continue;
1107
    }
1108
    if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
1109
    {
1110
      if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
1111
      {
1112
        /* Real unpleasant scenario but we continue anyways.  */
1113
        continue;
1114
      }
1115
    }
1116
  }
1117
  close_ddl_log();
1118
  create_ddl_log_file_name(file_name);
1119
  VOID(my_delete(file_name, MYF(0)));
1120
  global_ddl_log.recovery_phase= FALSE;
1121
  delete thd;
1122
  /* Remember that we don't have a THD */
1123
  my_pthread_setspecific_ptr(THR_THD,  0);
1124
  DBUG_VOID_RETURN;
1125
}
1126
1127
1128
/*
1129
  Release all memory allocated to the ddl log
1130
  SYNOPSIS
1131
    release_ddl_log()
1132
  RETURN VALUES
1133
    NONE
1134
*/
1135
1136
void release_ddl_log()
1137
{
1138
  DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
1139
  DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
1140
  DBUG_ENTER("release_ddl_log");
1141
1142
  if (!global_ddl_log.do_release)
1143
    DBUG_VOID_RETURN;
1144
1145
  pthread_mutex_lock(&LOCK_gdl);
1146
  while (used_list)
1147
  {
1148
    DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
1149
    my_free(used_list, MYF(0));
1150
    used_list= tmp;
1151
  }
1152
  while (free_list)
1153
  {
1154
    DDL_LOG_MEMORY_ENTRY *tmp= free_list->next_log_entry;
1155
    my_free(free_list, MYF(0));
1156
    free_list= tmp;
1157
  }
1158
  close_ddl_log();
1159
  global_ddl_log.inited= 0;
1160
  pthread_mutex_unlock(&LOCK_gdl);
1161
  VOID(pthread_mutex_destroy(&LOCK_gdl));
1162
  global_ddl_log.do_release= false;
1163
  DBUG_VOID_RETURN;
1164
}
1165
1166
1167
/*
1168
---------------------------------------------------------------------------
1169
1170
  END MODULE DDL log
1171
  --------------------
1172
1173
---------------------------------------------------------------------------
1174
*/
1175
1176
1177
/*
1178
  SYNOPSIS
1179
    write_bin_log()
1180
    thd                           Thread object
1181
    clear_error                   is clear_error to be called
1182
    query                         Query to log
1183
    query_length                  Length of query
1184
1185
  RETURN VALUES
1186
    NONE
1187
1188
  DESCRIPTION
1189
    Write the binlog if open, routine used in multiple places in this
1190
    file
1191
*/
1192
1193
void write_bin_log(THD *thd, bool clear_error,
1194
                   char const *query, ulong query_length)
1195
{
1196
  if (mysql_bin_log.is_open())
1197
  {
1198
    if (clear_error)
1199
      thd->clear_error();
1200
    thd->binlog_query(THD::STMT_QUERY_TYPE,
1201
                      query, query_length, FALSE, FALSE);
1202
  }
1203
}
1204
1205
1206
/*
1207
 delete (drop) tables.
1208
1209
  SYNOPSIS
1210
   mysql_rm_table()
1211
   thd			Thread handle
1212
   tables		List of tables to delete
1213
   if_exists		If 1, don't give error if one table doesn't exists
1214
1215
  NOTES
1216
    Will delete all tables that can be deleted and give a compact error
1217
    messages for tables that could not be deleted.
1218
    If a table is in use, we will wait for all users to free the table
1219
    before dropping it
1220
1221
    Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set, but
1222
    not if under LOCK TABLES.
1223
1224
  RETURN
1225
    FALSE OK.  In this case ok packet is sent to user
1226
    TRUE  Error
1227
1228
*/
1229
1230
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
1231
                    my_bool drop_temporary)
1232
{
1233
  bool error, need_start_waiting= FALSE;
1234
  DBUG_ENTER("mysql_rm_table");
1235
1236
  if (tables && tables->schema_table)
1237
  {
1238
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
1239
    DBUG_RETURN(TRUE);
1240
  }
1241
1242
  /* mark for close and remove all cached entries */
1243
1244
  if (!drop_temporary)
1245
  {
1246
    if (!thd->locked_tables &&
1247
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1248
      DBUG_RETURN(TRUE);
1249
  }
1250
1251
  /*
1252
    Acquire LOCK_open after wait_if_global_read_lock(). If we would hold
1253
    LOCK_open during wait_if_global_read_lock(), other threads could not
1254
    close their tables. This would make a pretty deadlock.
1255
  */
1256
  error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
1257
1258
  if (need_start_waiting)
1259
    start_waiting_global_read_lock(thd);
1260
1261
  if (error)
1262
    DBUG_RETURN(TRUE);
1263
  my_ok(thd);
1264
  DBUG_RETURN(FALSE);
1265
}
1266
1267
/*
1268
  Execute the drop of a normal or temporary table
1269
1270
  SYNOPSIS
1271
    mysql_rm_table_part2()
1272
    thd			Thread handler
1273
    tables		Tables to drop
1274
    if_exists		If set, don't give an error if table doesn't exists.
1275
			In this case we give an warning of level 'NOTE'
1276
    drop_temporary	Only drop temporary tables
1277
    drop_view		Allow to delete VIEW .frm
1278
    dont_log_query	Don't write query to log files. This will also not
1279
			generate warnings if the handler files doesn't exists  
1280
1281
  TODO:
1282
    When logging to the binary log, we should log
1283
    tmp_tables and transactional tables as separate statements if we
1284
    are in a transaction;  This is needed to get these tables into the
1285
    cached binary log that is only written on COMMIT.
1286
1287
   The current code only writes DROP statements that only uses temporary
1288
   tables to the cache binary log.  This should be ok on most cases, but
1289
   not all.
1290
1291
 RETURN
1292
   0	ok
1293
   1	Error
1294
   -1	Thread was killed
1295
*/
1296
1297
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
1298
                         bool drop_temporary, bool drop_view,
1299
                         bool dont_log_query)
1300
{
1301
  TABLE_LIST *table;
1302
  char path[FN_REFLEN], *alias;
1303
  uint path_length;
1304
  String wrong_tables;
1305
  int error= 0;
1306
  int non_temp_tables_count= 0;
1307
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
1308
  String built_query;
1309
  DBUG_ENTER("mysql_rm_table_part2");
1310
1311
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
1312
  {
1313
    built_query.set_charset(system_charset_info);
1314
    if (if_exists)
1315
      built_query.append("DROP TABLE IF EXISTS ");
1316
    else
1317
      built_query.append("DROP TABLE ");
1318
  }
1319
1320
  mysql_ha_rm_tables(thd, tables, FALSE);
1321
1322
  pthread_mutex_lock(&LOCK_open);
1323
1324
  /*
1325
    If we have the table in the definition cache, we don't have to check the
1326
    .frm file to find if the table is a normal table (not view) and what
1327
    engine to use.
1328
  */
1329
1330
  for (table= tables; table; table= table->next_local)
1331
  {
1332
    TABLE_SHARE *share;
1333
    table->db_type= NULL;
1334
    if ((share= get_cached_table_share(table->db, table->table_name)))
1335
      table->db_type= share->db_type();
1336
  }
1337
1338
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
1339
  {
1340
    pthread_mutex_unlock(&LOCK_open);
1341
    DBUG_RETURN(1);
1342
  }
1343
1344
  /* Don't give warnings for not found errors, as we already generate notes */
1345
  thd->no_warnings_for_error= 1;
1346
1347
  for (table= tables; table; table= table->next_local)
1348
  {
1349
    char *db=table->db;
1350
    handlerton *table_type;
1351
    enum legacy_db_type frm_db_type;
1352
1353
    DBUG_PRINT("table", ("table_l: '%s'.'%s'  table: 0x%lx  s: 0x%lx",
1354
                         table->db, table->table_name, (long) table->table,
1355
                         table->table ? (long) table->table->s : (long) -1));
1356
1357
    error= drop_temporary_table(thd, table);
1358
1359
    switch (error) {
1360
    case  0:
1361
      // removed temporary table
1362
      tmp_table_deleted= 1;
1363
      continue;
1364
    case -1:
1365
      DBUG_ASSERT(thd->in_sub_stmt);
1366
      error= 1;
1367
      goto err_with_placeholders;
1368
    default:
1369
      // temporary table not found
1370
      error= 0;
1371
    }
1372
1373
    /*
1374
      If row-based replication is used and the table is not a
1375
      temporary table, we add the table name to the drop statement
1376
      being built.  The string always end in a comma and the comma
1377
      will be chopped off before being written to the binary log.
1378
      */
1379
    if (thd->current_stmt_binlog_row_based && !dont_log_query)
1380
    {
1381
      non_temp_tables_count++;
1382
      /*
1383
        Don't write the database name if it is the current one (or if
1384
        thd->db is NULL).
1385
      */
1386
      built_query.append("`");
1387
      if (thd->db == NULL || strcmp(db,thd->db) != 0)
1388
      {
1389
        built_query.append(db);
1390
        built_query.append("`.`");
1391
      }
1392
1393
      built_query.append(table->table_name);
1394
      built_query.append("`,");
1395
    }
1396
1397
    table_type= table->db_type;
1398
    if (!drop_temporary)
1399
    {
1400
      TABLE *locked_table;
1401
      abort_locked_tables(thd, db, table->table_name);
1402
      remove_table_from_cache(thd, db, table->table_name,
1403
                              RTFC_WAIT_OTHER_THREAD_FLAG |
1404
                              RTFC_CHECK_KILLED_FLAG);
1405
      /*
1406
        If the table was used in lock tables, remember it so that
1407
        unlock_table_names can free it
1408
      */
1409
      if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
1410
        table->table= locked_table;
1411
1412
      if (thd->killed)
1413
      {
1414
        error= -1;
1415
        goto err_with_placeholders;
1416
      }
1417
      alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
1418
      /* remove .frm file and engine files */
1419
      path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
1420
                                        table->internal_tmp_table ?
1421
                                        FN_IS_TMP : 0);
1422
    }
1423
    if (drop_temporary ||
1424
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
1425
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
1426
    {
1427
      // Table was not found on disk and table can't be created from engine
1428
      if (if_exists)
1429
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1430
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
1431
                            table->table_name);
1432
      else
1433
        error= 1;
1434
    }
1435
    else
1436
    {
1437
      char *end;
1438
      if (table_type == NULL)
1439
      {
1440
        mysql_frm_type(thd, path, &frm_db_type);
1441
        table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
1442
      }
1443
      // Remove extension for delete
1444
      *(end= path + path_length - reg_ext_length)= '\0';
1445
      error= ha_delete_table(thd, table_type, path, db, table->table_name,
1446
                             !dont_log_query);
1447
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
1448
	  (if_exists || table_type == NULL))
1449
      {
1450
	error= 0;
1451
        thd->clear_error();
1452
      }
1453
      if (error == HA_ERR_ROW_IS_REFERENCED)
1454
      {
1455
        /* the table is referenced by a foreign key constraint */
1456
        foreign_key_error=1;
1457
      }
1458
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
1459
      {
1460
        int new_error;
1461
        /* Delete the table definition file */
1462
        strmov(end,reg_ext);
1463
        if (!(new_error=my_delete(path,MYF(MY_WME))))
1464
        {
1465
          some_tables_deleted=1;
1466
          new_error= 0;
1467
        }
1468
        error|= new_error;
1469
      }
1470
    }
1471
    if (error)
1472
    {
1473
      if (wrong_tables.length())
1474
        wrong_tables.append(',');
1475
      wrong_tables.append(String(table->table_name,system_charset_info));
1476
    }
1477
    DBUG_PRINT("table", ("table: 0x%lx  s: 0x%lx", (long) table->table,
1478
                         table->table ? (long) table->table->s : (long) -1));
1479
  }
1480
  /*
1481
    It's safe to unlock LOCK_open: we have an exclusive lock
1482
    on the table name.
1483
  */
1484
  pthread_mutex_unlock(&LOCK_open);
1485
  thd->thread_specific_used|= tmp_table_deleted;
1486
  error= 0;
1487
  if (wrong_tables.length())
1488
  {
1489
    if (!foreign_key_error)
1490
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
1491
                      wrong_tables.c_ptr());
1492
    else
1493
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
1494
    error= 1;
1495
  }
1496
1497
  if (some_tables_deleted || tmp_table_deleted || !error)
1498
  {
1499
    if (!dont_log_query)
1500
    {
1501
      if (!thd->current_stmt_binlog_row_based ||
1502
          (non_temp_tables_count > 0 && !tmp_table_deleted))
1503
      {
1504
        /*
1505
          In this case, we are either using statement-based
1506
          replication or using row-based replication but have only
1507
          deleted one or more non-temporary tables (and no temporary
1508
          tables).  In this case, we can write the original query into
1509
          the binary log.
1510
         */
1511
        write_bin_log(thd, !error, thd->query, thd->query_length);
1512
      }
1513
      else if (thd->current_stmt_binlog_row_based &&
1514
               non_temp_tables_count > 0 &&
1515
               tmp_table_deleted)
1516
      {
1517
        /*
1518
          In this case we have deleted both temporary and
1519
          non-temporary tables, so:
1520
          - since we have deleted a non-temporary table we have to
1521
            binlog the statement, but
1522
          - since we have deleted a temporary table we cannot binlog
1523
            the statement (since the table has not been created on the
1524
            slave, this might cause the slave to stop).
1525
1526
          Instead, we write a built statement, only containing the
1527
          non-temporary tables, to the binary log
1528
        */
1529
        built_query.chop();                  // Chop of the last comma
1530
        built_query.append(" /* generated by server */");
1531
        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
1532
      }
1533
      /*
1534
        The remaining cases are:
1535
        - no tables where deleted and
1536
        - only temporary tables where deleted and row-based
1537
          replication is used.
1538
        In both these cases, nothing should be written to the binary
1539
        log.
1540
      */
1541
    }
1542
  }
1543
  pthread_mutex_lock(&LOCK_open);
1544
err_with_placeholders:
1545
  unlock_table_names(thd, tables, (TABLE_LIST*) 0);
1546
  pthread_mutex_unlock(&LOCK_open);
1547
  thd->no_warnings_for_error= 0;
1548
  DBUG_RETURN(error);
1549
}
1550
1551
1552
/*
1553
  Quickly remove a table.
1554
1555
  SYNOPSIS
1556
    quick_rm_table()
1557
      base                      The handlerton handle.
1558
      db                        The database name.
1559
      table_name                The table name.
1560
      flags                     flags for build_table_filename().
1561
1562
  RETURN
1563
    0           OK
1564
    != 0        Error
1565
*/
1566
1567
bool quick_rm_table(handlerton *base,const char *db,
1568
                    const char *table_name, uint flags)
1569
{
1570
  char path[FN_REFLEN];
1571
  bool error= 0;
1572
  DBUG_ENTER("quick_rm_table");
1573
1574
  uint path_length= build_table_filename(path, sizeof(path),
1575
                                         db, table_name, reg_ext, flags);
1576
  if (my_delete(path,MYF(0)))
1577
    error= 1; /* purecov: inspected */
1578
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
1579
  DBUG_RETURN(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
1580
              error);
1581
}
1582
1583
/*
1584
  Sort keys in the following order:
1585
  - PRIMARY KEY
1586
  - UNIQUE keys where all column are NOT NULL
1587
  - UNIQUE keys that don't contain partial segments
1588
  - Other UNIQUE keys
1589
  - Normal keys
1590
  - Fulltext keys
1591
1592
  This will make checking for duplicated keys faster and ensure that
1593
  PRIMARY keys are prioritized.
1594
*/
1595
1596
static int sort_keys(KEY *a, KEY *b)
1597
{
1598
  ulong a_flags= a->flags, b_flags= b->flags;
1599
  
1600
  if (a_flags & HA_NOSAME)
1601
  {
1602
    if (!(b_flags & HA_NOSAME))
1603
      return -1;
1604
    if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
1605
    {
1606
      /* Sort NOT NULL keys before other keys */
1607
      return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
1608
    }
1609
    if (a->name == primary_key_name)
1610
      return -1;
1611
    if (b->name == primary_key_name)
1612
      return 1;
1613
    /* Sort keys don't containing partial segments before others */
1614
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
1615
      return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
1616
  }
1617
  else if (b_flags & HA_NOSAME)
1618
    return 1;					// Prefer b
1619
1620
  /*
1621
    Prefer original key order.	usable_key_parts contains here
1622
    the original key position.
1623
  */
1624
  return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
1625
          (a->usable_key_parts > b->usable_key_parts) ? 1 :
1626
          0);
1627
}
1628
1629
/*
1630
  Check TYPELIB (set or enum) for duplicates
1631
1632
  SYNOPSIS
1633
    check_duplicates_in_interval()
1634
    set_or_name   "SET" or "ENUM" string for warning message
1635
    name	  name of the checked column
1636
    typelib	  list of values for the column
1637
    dup_val_count  returns count of duplicate elements
1638
1639
  DESCRIPTION
1640
    This function prints an warning for each value in list
1641
    which has some duplicates on its right
1642
1643
  RETURN VALUES
1644
    0             ok
1645
    1             Error
1646
*/
1647
1648
bool check_duplicates_in_interval(const char *set_or_name,
1649
                                  const char *name, TYPELIB *typelib,
1650
                                  CHARSET_INFO *cs, unsigned int *dup_val_count)
1651
{
1652
  TYPELIB tmp= *typelib;
1653
  const char **cur_value= typelib->type_names;
1654
  unsigned int *cur_length= typelib->type_lengths;
1655
  *dup_val_count= 0;  
1656
  
1657
  for ( ; tmp.count > 1; cur_value++, cur_length++)
1658
  {
1659
    tmp.type_names++;
1660
    tmp.type_lengths++;
1661
    tmp.count--;
1662
    if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
1663
    {
1664
      my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
1665
               name,*cur_value,set_or_name);
1666
      return 1;
1667
    }
1668
  }
1669
  return 0;
1670
}
1671
1672
1673
/*
1674
  Check TYPELIB (set or enum) max and total lengths
1675
1676
  SYNOPSIS
1677
    calculate_interval_lengths()
1678
    cs            charset+collation pair of the interval
1679
    typelib       list of values for the column
1680
    max_length    length of the longest item
1681
    tot_length    sum of the item lengths
1682
1683
  DESCRIPTION
1684
    After this function call:
1685
    - ENUM uses max_length
1686
    - SET uses tot_length.
1687
1688
  RETURN VALUES
1689
    void
1690
*/
1691
void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
1692
                                uint32 *max_length, uint32 *tot_length)
1693
{
1694
  const char **pos;
1695
  uint *len;
1696
  *max_length= *tot_length= 0;
1697
  for (pos= interval->type_names, len= interval->type_lengths;
1698
       *pos ; pos++, len++)
1699
  {
1700
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
1701
    *tot_length+= length;
1702
    set_if_bigger(*max_length, (uint32)length);
1703
  }
1704
}
1705
1706
1707
/*
1708
  Prepare a create_table instance for packing
1709
1710
  SYNOPSIS
1711
    prepare_create_field()
1712
    sql_field     field to prepare for packing
1713
    blob_columns  count for BLOBs
1714
    timestamps    count for timestamps
1715
    table_flags   table flags
1716
1717
  DESCRIPTION
1718
    This function prepares a Create_field instance.
1719
    Fields such as pack_flag are valid after this call.
1720
1721
  RETURN VALUES
1722
   0	ok
1723
   1	Error
1724
*/
1725
1726
int prepare_create_field(Create_field *sql_field, 
1727
                         uint *blob_columns,
1728
                         int *timestamps, int *timestamps_with_niladic,
1729
                         longlong table_flags)
1730
{
1731
  unsigned int dup_val_count;
1732
  DBUG_ENTER("prepare_field");
1733
1734
  /*
1735
    This code came from mysql_prepare_create_table.
1736
    Indent preserved to make patching easier
1737
  */
1738
  DBUG_ASSERT(sql_field->charset);
1739
1740
  switch (sql_field->sql_type) {
1741
  case MYSQL_TYPE_BLOB:
1742
  case MYSQL_TYPE_MEDIUM_BLOB:
1743
  case MYSQL_TYPE_TINY_BLOB:
1744
  case MYSQL_TYPE_LONG_BLOB:
1745
    sql_field->pack_flag=FIELDFLAG_BLOB |
1746
      pack_length_to_packflag(sql_field->pack_length -
1747
                              portable_sizeof_char_ptr);
1748
    if (sql_field->charset->state & MY_CS_BINSORT)
1749
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1750
    sql_field->length=8;			// Unireg field length
1751
    sql_field->unireg_check=Field::BLOB_FIELD;
1752
    (*blob_columns)++;
1753
    break;
1754
  case MYSQL_TYPE_VARCHAR:
1755
#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
1756
    if (table_flags & HA_NO_VARCHAR)
1757
    {
1758
      /* convert VARCHAR to CHAR because handler is not yet up to date */
1759
      sql_field->sql_type=    MYSQL_TYPE_VAR_STRING;
1760
      sql_field->pack_length= calc_pack_length(sql_field->sql_type,
1761
                                               (uint) sql_field->length);
1762
      if ((sql_field->length / sql_field->charset->mbmaxlen) >
1763
          MAX_FIELD_CHARLENGTH)
1764
      {
1765
        my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
1766
                        MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
1767
        DBUG_RETURN(1);
1768
      }
1769
    }
1770
#endif
1771
    /* fall through */
1772
  case MYSQL_TYPE_STRING:
1773
    sql_field->pack_flag=0;
1774
    if (sql_field->charset->state & MY_CS_BINSORT)
1775
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1776
    break;
1777
  case MYSQL_TYPE_ENUM:
1778
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
1779
      FIELDFLAG_INTERVAL;
1780
    if (sql_field->charset->state & MY_CS_BINSORT)
1781
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1782
    sql_field->unireg_check=Field::INTERVAL_FIELD;
1783
    if (check_duplicates_in_interval("ENUM",sql_field->field_name,
1784
                                 sql_field->interval,
1785
                                     sql_field->charset, &dup_val_count))
1786
      DBUG_RETURN(1);
1787
    break;
1788
  case MYSQL_TYPE_SET:
1789
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
1790
      FIELDFLAG_BITFIELD;
1791
    if (sql_field->charset->state & MY_CS_BINSORT)
1792
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1793
    sql_field->unireg_check=Field::BIT_FIELD;
1794
    if (check_duplicates_in_interval("SET",sql_field->field_name,
1795
                                 sql_field->interval,
1796
                                     sql_field->charset, &dup_val_count))
1797
      DBUG_RETURN(1);
1798
    /* Check that count of unique members is not more then 64 */
1799
    if (sql_field->interval->count -  dup_val_count > sizeof(longlong)*8)
1800
    {
1801
       my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
1802
       DBUG_RETURN(1);
1803
    }
1804
    break;
1805
  case MYSQL_TYPE_DATE:			// Rest of string types
1806
  case MYSQL_TYPE_NEWDATE:
1807
  case MYSQL_TYPE_TIME:
1808
  case MYSQL_TYPE_DATETIME:
1809
  case MYSQL_TYPE_NULL:
1810
    sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
1811
    break;
1812
  case MYSQL_TYPE_BIT:
1813
    /* 
1814
      We have sql_field->pack_flag already set here, see
1815
      mysql_prepare_create_table().
1816
    */
1817
    break;
1818
  case MYSQL_TYPE_NEWDECIMAL:
1819
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
1820
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
1821
                           FIELDFLAG_DECIMAL) |
1822
                          (sql_field->flags & ZEROFILL_FLAG ?
1823
                           FIELDFLAG_ZEROFILL : 0) |
1824
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
1825
    break;
1826
  case MYSQL_TYPE_TIMESTAMP:
1827
    /* We should replace old TIMESTAMP fields with their newer analogs */
1828
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
1829
    {
1830
      if (!*timestamps)
1831
      {
1832
        sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
1833
        (*timestamps_with_niladic)++;
1834
      }
1835
      else
1836
        sql_field->unireg_check= Field::NONE;
1837
    }
1838
    else if (sql_field->unireg_check != Field::NONE)
1839
      (*timestamps_with_niladic)++;
1840
1841
    (*timestamps)++;
1842
    /* fall-through */
1843
  default:
1844
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
1845
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
1846
                           FIELDFLAG_DECIMAL) |
1847
                          (sql_field->flags & ZEROFILL_FLAG ?
1848
                           FIELDFLAG_ZEROFILL : 0) |
1849
                          f_settype((uint) sql_field->sql_type) |
1850
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
1851
    break;
1852
  }
1853
  if (!(sql_field->flags & NOT_NULL_FLAG))
1854
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
1855
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
1856
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
1857
  DBUG_RETURN(0);
1858
}
1859
1860
/*
1861
  Preparation for table creation
1862
1863
  SYNOPSIS
1864
    mysql_prepare_create_table()
1865
      thd                       Thread object.
1866
      create_info               Create information (like MAX_ROWS).
1867
      alter_info                List of columns and indexes to create
1868
      tmp_table                 If a temporary table is to be created.
1869
      db_options          INOUT Table options (like HA_OPTION_PACK_RECORD).
1870
      file                      The handler for the new table.
1871
      key_info_buffer     OUT   An array of KEY structs for the indexes.
1872
      key_count           OUT   The number of elements in the array.
1873
      select_field_count        The number of fields coming from a select table.
1874
1875
  DESCRIPTION
1876
    Prepares the table and key structures for table creation.
1877
1878
  NOTES
1879
    sets create_info->varchar if the table has a varchar
1880
1881
  RETURN VALUES
1882
    FALSE    OK
1883
    TRUE     error
1884
*/
1885
1886
static int
1887
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
1888
                           Alter_info *alter_info,
1889
                           bool tmp_table,
1890
                               uint *db_options,
1891
                               handler *file, KEY **key_info_buffer,
1892
                               uint *key_count, int select_field_count)
1893
{
1894
  const char	*key_name;
1895
  Create_field	*sql_field,*dup_field;
1896
  uint		field,null_fields,blob_columns,max_key_length;
1897
  ulong		record_offset= 0;
1898
  KEY		*key_info;
1899
  KEY_PART_INFO *key_part_info;
1900
  int		timestamps= 0, timestamps_with_niladic= 0;
1901
  int		field_no,dup_no;
1902
  int		select_field_pos,auto_increment=0;
1903
  List_iterator<Create_field> it(alter_info->create_list);
1904
  List_iterator<Create_field> it2(alter_info->create_list);
1905
  uint total_uneven_bit_length= 0;
1906
  DBUG_ENTER("mysql_prepare_create_table");
1907
1908
  select_field_pos= alter_info->create_list.elements - select_field_count;
1909
  null_fields=blob_columns=0;
1910
  create_info->varchar= 0;
1911
  max_key_length= file->max_key_length();
1912
1913
  for (field_no=0; (sql_field=it++) ; field_no++)
1914
  {
1915
    CHARSET_INFO *save_cs;
1916
1917
    /*
1918
      Initialize length from its original value (number of characters),
1919
      which was set in the parser. This is necessary if we're
1920
      executing a prepared statement for the second time.
1921
    */
1922
    sql_field->length= sql_field->char_length;
1923
    if (!sql_field->charset)
1924
      sql_field->charset= create_info->default_table_charset;
1925
    /*
1926
      table_charset is set in ALTER TABLE if we want change character set
1927
      for all varchar/char columns.
1928
      But the table charset must not affect the BLOB fields, so don't
1929
      allow to change my_charset_bin to somethig else.
1930
    */
1931
    if (create_info->table_charset && sql_field->charset != &my_charset_bin)
1932
      sql_field->charset= create_info->table_charset;
1933
1934
    save_cs= sql_field->charset;
1935
    if ((sql_field->flags & BINCMP_FLAG) &&
1936
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
1937
                                                    MY_CS_BINSORT,MYF(0))))
1938
    {
1939
      char tmp[64];
1940
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
1941
              STRING_WITH_LEN("_bin"));
1942
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
1943
      DBUG_RETURN(TRUE);
1944
    }
1945
1946
    /*
1947
      Convert the default value from client character
1948
      set into the column character set if necessary.
1949
    */
1950
    if (sql_field->def && 
1951
        save_cs != sql_field->def->collation.collation &&
1952
        (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
1953
         sql_field->sql_type == MYSQL_TYPE_STRING ||
1954
         sql_field->sql_type == MYSQL_TYPE_SET ||
1955
         sql_field->sql_type == MYSQL_TYPE_ENUM))
1956
    {
1957
      /*
1958
        Starting from 5.1 we work here with a copy of Create_field
1959
        created by the caller, not with the instance that was
1960
        originally created during parsing. It's OK to create
1961
        a temporary item and initialize with it a member of the
1962
        copy -- this item will be thrown away along with the copy
1963
        at the end of execution, and thus not introduce a dangling
1964
        pointer in the parsed tree of a prepared statement or a
1965
        stored procedure statement.
1966
      */
1967
      sql_field->def= sql_field->def->safe_charset_converter(save_cs);
1968
1969
      if (sql_field->def == NULL)
1970
      {
1971
        /* Could not convert */
1972
        my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1973
        DBUG_RETURN(TRUE);
1974
      }
1975
    }
1976
1977
    if (sql_field->sql_type == MYSQL_TYPE_SET ||
1978
        sql_field->sql_type == MYSQL_TYPE_ENUM)
1979
    {
1980
      uint32 dummy;
1981
      CHARSET_INFO *cs= sql_field->charset;
1982
      TYPELIB *interval= sql_field->interval;
1983
1984
      /*
1985
        Create typelib from interval_list, and if necessary
1986
        convert strings from client character set to the
1987
        column character set.
1988
      */
1989
      if (!interval)
1990
      {
1991
        /*
1992
          Create the typelib in runtime memory - we will free the
1993
          occupied memory at the same time when we free this
1994
          sql_field -- at the end of execution.
1995
        */
1996
        interval= sql_field->interval= typelib(thd->mem_root,
1997
                                               sql_field->interval_list);
1998
        List_iterator<String> int_it(sql_field->interval_list);
1999
        String conv, *tmp;
2000
        char comma_buf[4];
2001
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
2002
                                          (uchar*) comma_buf + 
2003
                                          sizeof(comma_buf));
2004
        DBUG_ASSERT(comma_length > 0);
2005
        for (uint i= 0; (tmp= int_it++); i++)
2006
        {
2007
          uint lengthsp;
2008
          if (String::needs_conversion(tmp->length(), tmp->charset(),
2009
                                       cs, &dummy))
2010
          {
2011
            uint cnv_errs;
2012
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
2013
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
2014
                                                  conv.length());
2015
            interval->type_lengths[i]= conv.length();
2016
          }
2017
2018
          // Strip trailing spaces.
2019
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
2020
                                       interval->type_lengths[i]);
2021
          interval->type_lengths[i]= lengthsp;
2022
          ((uchar *)interval->type_names[i])[lengthsp]= '\0';
2023
          if (sql_field->sql_type == MYSQL_TYPE_SET)
2024
          {
2025
            if (cs->coll->instr(cs, interval->type_names[i], 
2026
                                interval->type_lengths[i], 
2027
                                comma_buf, comma_length, NULL, 0))
2028
            {
2029
              my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
2030
              DBUG_RETURN(TRUE);
2031
            }
2032
          }
2033
        }
2034
        sql_field->interval_list.empty(); // Don't need interval_list anymore
2035
      }
2036
2037
      if (sql_field->sql_type == MYSQL_TYPE_SET)
2038
      {
2039
        uint32 field_length;
2040
        if (sql_field->def != NULL)
2041
        {
2042
          char *not_used;
2043
          uint not_used2;
2044
          bool not_found= 0;
2045
          String str, *def= sql_field->def->val_str(&str);
2046
          if (def == NULL) /* SQL "NULL" maps to NULL */
2047
          {
2048
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
2049
            {
2050
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2051
              DBUG_RETURN(TRUE);
2052
            }
2053
2054
            /* else, NULL is an allowed value */
2055
            (void) find_set(interval, NULL, 0,
2056
                            cs, &not_used, &not_used2, &not_found);
2057
          }
2058
          else /* not NULL */
2059
          {
2060
            (void) find_set(interval, def->ptr(), def->length(),
2061
                            cs, &not_used, &not_used2, &not_found);
2062
          }
2063
2064
          if (not_found)
2065
          {
2066
            my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2067
            DBUG_RETURN(TRUE);
2068
          }
2069
        }
2070
        calculate_interval_lengths(cs, interval, &dummy, &field_length);
2071
        sql_field->length= field_length + (interval->count - 1);
2072
      }
2073
      else  /* MYSQL_TYPE_ENUM */
2074
      {
2075
        uint32 field_length;
2076
        DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
2077
        if (sql_field->def != NULL)
2078
        {
2079
          String str, *def= sql_field->def->val_str(&str);
2080
          if (def == NULL) /* SQL "NULL" maps to NULL */
2081
          {
2082
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
2083
            {
2084
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2085
              DBUG_RETURN(TRUE);
2086
            }
2087
2088
            /* else, the defaults yield the correct length for NULLs. */
2089
          } 
2090
          else /* not NULL */
2091
          {
2092
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
2093
            if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
2094
            {
2095
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2096
              DBUG_RETURN(TRUE);
2097
            }
2098
          }
2099
        }
2100
        calculate_interval_lengths(cs, interval, &field_length, &dummy);
2101
        sql_field->length= field_length;
2102
      }
2103
      set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
2104
    }
2105
2106
    if (sql_field->sql_type == MYSQL_TYPE_BIT)
2107
    { 
2108
      sql_field->pack_flag= FIELDFLAG_NUMBER;
2109
      if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
2110
        total_uneven_bit_length+= sql_field->length & 7;
2111
      else
2112
        sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
2113
    }
2114
2115
    sql_field->create_length_to_internal_length();
2116
    if (prepare_blob_field(thd, sql_field))
2117
      DBUG_RETURN(TRUE);
2118
2119
    if (!(sql_field->flags & NOT_NULL_FLAG))
2120
      null_fields++;
2121
2122
    if (check_column_name(sql_field->field_name))
2123
    {
2124
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
2125
      DBUG_RETURN(TRUE);
2126
    }
2127
2128
    /* Check if we have used the same field name before */
2129
    for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
2130
    {
2131
      if (my_strcasecmp(system_charset_info,
2132
                        sql_field->field_name,
2133
                        dup_field->field_name) == 0)
2134
      {
2135
	/*
2136
	  If this was a CREATE ... SELECT statement, accept a field
2137
	  redefinition if we are changing a field in the SELECT part
2138
	*/
2139
	if (field_no < select_field_pos || dup_no >= select_field_pos)
2140
	{
2141
	  my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
2142
	  DBUG_RETURN(TRUE);
2143
	}
2144
	else
2145
	{
2146
	  /* Field redefined */
2147
	  sql_field->def=		dup_field->def;
2148
	  sql_field->sql_type=		dup_field->sql_type;
2149
	  sql_field->charset=		(dup_field->charset ?
2150
					 dup_field->charset :
2151
					 create_info->default_table_charset);
2152
	  sql_field->length=		dup_field->char_length;
2153
          sql_field->pack_length=	dup_field->pack_length;
2154
          sql_field->key_length=	dup_field->key_length;
2155
	  sql_field->decimals=		dup_field->decimals;
2156
	  sql_field->create_length_to_internal_length();
2157
	  sql_field->unireg_check=	dup_field->unireg_check;
2158
          /* 
2159
            We're making one field from two, the result field will have
2160
            dup_field->flags as flags. If we've incremented null_fields
2161
            because of sql_field->flags, decrement it back.
2162
          */
2163
          if (!(sql_field->flags & NOT_NULL_FLAG))
2164
            null_fields--;
2165
	  sql_field->flags=		dup_field->flags;
2166
          sql_field->interval=          dup_field->interval;
2167
	  it2.remove();			// Remove first (create) definition
2168
	  select_field_pos--;
2169
	  break;
2170
	}
2171
      }
2172
    }
2173
    /* Don't pack rows in old tables if the user has requested this */
2174
    if ((sql_field->flags & BLOB_FLAG) ||
2175
	(sql_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
2176
      (*db_options)|= HA_OPTION_PACK_RECORD;
2177
    it2.rewind();
2178
  }
2179
2180
  /* record_offset will be increased with 'length-of-null-bits' later */
2181
  record_offset= 0;
2182
  null_fields+= total_uneven_bit_length;
2183
2184
  it.rewind();
2185
  while ((sql_field=it++))
2186
  {
2187
    DBUG_ASSERT(sql_field->charset != 0);
2188
2189
    if (prepare_create_field(sql_field, &blob_columns, 
2190
			     &timestamps, &timestamps_with_niladic,
2191
			     file->ha_table_flags()))
2192
      DBUG_RETURN(TRUE);
2193
    if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
2194
      create_info->varchar= TRUE;
2195
    sql_field->offset= record_offset;
2196
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
2197
      auto_increment++;
2198
    record_offset+= sql_field->pack_length;
2199
  }
2200
  if (timestamps_with_niladic > 1)
2201
  {
2202
    my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
2203
               ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
2204
    DBUG_RETURN(TRUE);
2205
  }
2206
  if (auto_increment > 1)
2207
  {
2208
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
2209
    DBUG_RETURN(TRUE);
2210
  }
2211
  if (auto_increment &&
2212
      (file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
2213
  {
2214
    my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
2215
               ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
2216
    DBUG_RETURN(TRUE);
2217
  }
2218
2219
  if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
2220
  {
2221
    my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
2222
               MYF(0));
2223
    DBUG_RETURN(TRUE);
2224
  }
2225
2226
  /* Create keys */
2227
2228
  List_iterator<Key> key_iterator(alter_info->key_list);
2229
  List_iterator<Key> key_iterator2(alter_info->key_list);
2230
  uint key_parts=0, fk_key_count=0;
2231
  bool primary_key=0,unique_key=0;
2232
  Key *key, *key2;
2233
  uint tmp, key_number;
2234
  /* special marker for keys to be ignored */
2235
  static char ignore_key[1];
2236
2237
  /* Calculate number of key segements */
2238
  *key_count= 0;
2239
2240
  while ((key=key_iterator++))
2241
  {
2242
    DBUG_PRINT("info", ("key name: '%s'  type: %d", key->name.str ? key->name.str :
2243
                        "(none)" , key->type));
2244
    if (key->type == Key::FOREIGN_KEY)
2245
    {
2246
      fk_key_count++;
2247
      Foreign_key *fk_key= (Foreign_key*) key;
2248
      if (fk_key->ref_columns.elements &&
2249
	  fk_key->ref_columns.elements != fk_key->columns.elements)
2250
      {
2251
        my_error(ER_WRONG_FK_DEF, MYF(0),
2252
                 (fk_key->name.str ? fk_key->name.str :
2253
                                     "foreign key without name"),
2254
                 ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
2255
	DBUG_RETURN(TRUE);
2256
      }
2257
      continue;
2258
    }
2259
    (*key_count)++;
2260
    tmp=file->max_key_parts();
2261
    if (key->columns.elements > tmp)
2262
    {
2263
      my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
2264
      DBUG_RETURN(TRUE);
2265
    }
2266
    if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))
2267
      DBUG_RETURN(TRUE);
2268
    key_iterator2.rewind ();
2269
    if (key->type != Key::FOREIGN_KEY)
2270
    {
2271
      while ((key2 = key_iterator2++) != key)
2272
      {
2273
	/*
2274
          foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is
2275
          'generated', and a generated key is a prefix of the other key.
2276
          Then we do not need the generated shorter key.
2277
        */
2278
        if ((key2->type != Key::FOREIGN_KEY &&
2279
             key2->name.str != ignore_key &&
2280
             !foreign_key_prefix(key, key2)))
2281
        {
2282
          /* TODO: issue warning message */
2283
          /* mark that the generated key should be ignored */
2284
          if (!key2->generated ||
2285
              (key->generated && key->columns.elements <
2286
               key2->columns.elements))
2287
            key->name.str= ignore_key;
2288
          else
2289
          {
2290
            key2->name.str= ignore_key;
2291
            key_parts-= key2->columns.elements;
2292
            (*key_count)--;
2293
          }
2294
          break;
2295
        }
2296
      }
2297
    }
2298
    if (key->name.str != ignore_key)
2299
      key_parts+=key->columns.elements;
2300
    else
2301
      (*key_count)--;
2302
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
2303
	!my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
2304
    {
2305
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
2306
      DBUG_RETURN(TRUE);
2307
    }
2308
  }
2309
  tmp=file->max_keys();
2310
  if (*key_count > tmp)
2311
  {
2312
    my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
2313
    DBUG_RETURN(TRUE);
2314
  }
2315
2316
  (*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));
2317
  key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
2318
  if (!*key_info_buffer || ! key_part_info)
2319
    DBUG_RETURN(TRUE);				// Out of memory
2320
2321
  key_iterator.rewind();
2322
  key_number=0;
2323
  for (; (key=key_iterator++) ; key_number++)
2324
  {
2325
    uint key_length=0;
2326
    Key_part_spec *column;
2327
2328
    if (key->name.str == ignore_key)
2329
    {
2330
      /* ignore redundant keys */
2331
      do
2332
	key=key_iterator++;
2333
      while (key && key->name.str == ignore_key);
2334
      if (!key)
2335
	break;
2336
    }
2337
2338
    switch (key->type) {
2339
    case Key::MULTIPLE:
2340
	key_info->flags= 0;
2341
	break;
2342
    case Key::FOREIGN_KEY:
2343
      key_number--;				// Skip this key
2344
      continue;
2345
    default:
2346
      key_info->flags = HA_NOSAME;
2347
      break;
2348
    }
2349
    if (key->generated)
2350
      key_info->flags|= HA_GENERATED_KEY;
2351
2352
    key_info->key_parts=(uint8) key->columns.elements;
2353
    key_info->key_part=key_part_info;
2354
    key_info->usable_key_parts= key_number;
2355
    key_info->algorithm= key->key_create_info.algorithm;
2356
2357
    /* Take block size from key part or table part */
2358
    /*
2359
      TODO: Add warning if block size changes. We can't do it here, as
2360
      this may depend on the size of the key
2361
    */
2362
    key_info->block_size= (key->key_create_info.block_size ?
2363
                           key->key_create_info.block_size :
2364
                           create_info->key_block_size);
2365
2366
    if (key_info->block_size)
2367
      key_info->flags|= HA_USES_BLOCK_SIZE;
2368
2369
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
2370
                                           key->key_create_info.comment.str,
2371
                                           key->key_create_info.comment.str +
2372
                                           key->key_create_info.comment.length,
2373
                                           INDEX_COMMENT_MAXLEN);
2374
2375
    if (tmp_len < key->key_create_info.comment.length)
2376
    {
2377
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
2378
               key->key_create_info.comment.str,"INDEX COMMENT",
2379
               (uint) INDEX_COMMENT_MAXLEN);
2380
      DBUG_RETURN(-1);
2381
    }
2382
2383
    key_info->comment.length= key->key_create_info.comment.length;
2384
    if (key_info->comment.length > 0)
2385
    {
2386
      key_info->flags|= HA_USES_COMMENT;
2387
      key_info->comment.str= key->key_create_info.comment.str;
2388
    }
2389
2390
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
2391
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
2392
    {
2393
      uint length;
2394
      Key_part_spec *dup_column;
2395
2396
      it.rewind();
2397
      field=0;
2398
      while ((sql_field=it++) &&
2399
	     my_strcasecmp(system_charset_info,
2400
			   column->field_name.str,
2401
			   sql_field->field_name))
2402
	field++;
2403
      if (!sql_field)
2404
      {
2405
	my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
2406
	DBUG_RETURN(TRUE);
2407
      }
2408
      while ((dup_column= cols2++) != column)
2409
      {
2410
        if (!my_strcasecmp(system_charset_info,
2411
	     	           column->field_name.str, dup_column->field_name.str))
2412
	{
2413
	  my_printf_error(ER_DUP_FIELDNAME,
2414
			  ER(ER_DUP_FIELDNAME),MYF(0),
2415
			  column->field_name.str);
2416
	  DBUG_RETURN(TRUE);
2417
	}
2418
      }
2419
      cols2.rewind();
2420
      {
2421
	column->length*= sql_field->charset->mbmaxlen;
2422
2423
	if (f_is_blob(sql_field->pack_flag))
2424
	{
2425
	  if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
2426
	  {
2427
	    my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
2428
	    DBUG_RETURN(TRUE);
2429
	  }
2430
	  if (!column->length)
2431
	  {
2432
	    my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
2433
	    DBUG_RETURN(TRUE);
2434
	  }
2435
	}
2436
	if (!(sql_field->flags & NOT_NULL_FLAG))
2437
	{
2438
	  if (key->type == Key::PRIMARY)
2439
	  {
2440
	    /* Implicitly set primary key fields to NOT NULL for ISO conf. */
2441
	    sql_field->flags|= NOT_NULL_FLAG;
2442
	    sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
2443
            null_fields--;
2444
	  }
2445
	  else
2446
          {
2447
            key_info->flags|= HA_NULL_PART_KEY;
2448
            if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
2449
            {
2450
              my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
2451
              DBUG_RETURN(TRUE);
2452
            }
2453
          }
2454
	}
2455
	if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
2456
	{
2457
	  if (column_nr == 0 || (file->ha_table_flags() & HA_AUTO_PART_KEY))
2458
	    auto_increment--;			// Field is used
2459
	}
2460
      }
2461
2462
      key_part_info->fieldnr= field;
2463
      key_part_info->offset=  (uint16) sql_field->offset;
2464
      key_part_info->key_type=sql_field->pack_flag;
2465
      length= sql_field->key_length;
2466
2467
      if (column->length)
2468
      {
2469
	if (f_is_blob(sql_field->pack_flag))
2470
	{
2471
	  if ((length=column->length) > max_key_length ||
2472
	      length > file->max_key_part_length())
2473
	  {
2474
	    length=min(max_key_length, file->max_key_part_length());
2475
	    if (key->type == Key::MULTIPLE)
2476
	    {
2477
	      /* not a critical problem */
2478
	      char warn_buff[MYSQL_ERRMSG_SIZE];
2479
	      my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
2480
			  length);
2481
	      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2482
			   ER_TOO_LONG_KEY, warn_buff);
2483
              /* Align key length to multibyte char boundary */
2484
              length-= length % sql_field->charset->mbmaxlen;
2485
	    }
2486
	    else
2487
	    {
2488
	      my_error(ER_TOO_LONG_KEY,MYF(0),length);
2489
	      DBUG_RETURN(TRUE);
2490
	    }
2491
	  }
2492
	}
2493
	else if ((column->length > length ||
2494
                   !Field::type_can_have_key_part (sql_field->sql_type) ||
2495
		   ((f_is_packed(sql_field->pack_flag) ||
2496
		     ((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
2497
		      (key_info->flags & HA_NOSAME))) &&
2498
		    column->length != length)))
2499
	{
2500
	  my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
2501
	  DBUG_RETURN(TRUE);
2502
	}
2503
	else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
2504
	  length=column->length;
2505
      }
2506
      else if (length == 0)
2507
      {
2508
	my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
2509
	  DBUG_RETURN(TRUE);
2510
      }
2511
      if (length > file->max_key_part_length())
2512
      {
2513
        length= file->max_key_part_length();
2514
	if (key->type == Key::MULTIPLE)
2515
	{
2516
	  /* not a critical problem */
2517
	  char warn_buff[MYSQL_ERRMSG_SIZE];
2518
	  my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
2519
		      length);
2520
	  push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
2521
		       ER_TOO_LONG_KEY, warn_buff);
2522
          /* Align key length to multibyte char boundary */
2523
          length-= length % sql_field->charset->mbmaxlen;
2524
	}
2525
	else
2526
	{
2527
	  my_error(ER_TOO_LONG_KEY,MYF(0),length);
2528
	  DBUG_RETURN(TRUE);
2529
	}
2530
      }
2531
      key_part_info->length=(uint16) length;
2532
      /* Use packed keys for long strings on the first column */
2533
      if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
2534
	  (length >= KEY_DEFAULT_PACK_LENGTH &&
2535
	   (sql_field->sql_type == MYSQL_TYPE_STRING ||
2536
	    sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
2537
	    sql_field->pack_flag & FIELDFLAG_BLOB)))
2538
      {
2539
	if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
2540
            sql_field->sql_type == MYSQL_TYPE_VARCHAR)
2541
	  key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
2542
	else
2543
	  key_info->flags|= HA_PACK_KEY;
2544
      }
2545
      /* Check if the key segment is partial, set the key flag accordingly */
2546
      if (length != sql_field->key_length)
2547
        key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
2548
2549
      key_length+=length;
2550
      key_part_info++;
2551
2552
      /* Create the key name based on the first column (if not given) */
2553
      if (column_nr == 0)
2554
      {
2555
	if (key->type == Key::PRIMARY)
2556
	{
2557
	  if (primary_key)
2558
	  {
2559
	    my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
2560
                       MYF(0));
2561
	    DBUG_RETURN(TRUE);
2562
	  }
2563
	  key_name=primary_key_name;
2564
	  primary_key=1;
2565
	}
2566
	else if (!(key_name= key->name.str))
2567
	  key_name=make_unique_key_name(sql_field->field_name,
2568
					*key_info_buffer, key_info);
2569
	if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
2570
	{
2571
	  my_error(ER_DUP_KEYNAME, MYF(0), key_name);
2572
	  DBUG_RETURN(TRUE);
2573
	}
2574
	key_info->name=(char*) key_name;
2575
      }
2576
    }
2577
    if (!key_info->name || check_column_name(key_info->name))
2578
    {
2579
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
2580
      DBUG_RETURN(TRUE);
2581
    }
2582
    if (!(key_info->flags & HA_NULL_PART_KEY))
2583
      unique_key=1;
2584
    key_info->key_length=(uint16) key_length;
2585
    if (key_length > max_key_length)
2586
    {
2587
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
2588
      DBUG_RETURN(TRUE);
2589
    }
2590
    key_info++;
2591
  }
2592
  if (!unique_key && !primary_key &&
2593
      (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
2594
  {
2595
    my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
2596
    DBUG_RETURN(TRUE);
2597
  }
2598
  if (auto_increment > 0)
2599
  {
2600
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
2601
    DBUG_RETURN(TRUE);
2602
  }
2603
  /* Sort keys in optimized order */
2604
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
2605
	   (qsort_cmp) sort_keys);
2606
  create_info->null_bits= null_fields;
2607
2608
  /* Check fields. */
2609
  it.rewind();
2610
  while ((sql_field=it++))
2611
  {
2612
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
2613
2614
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
2615
        !sql_field->def &&
2616
        sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
2617
        (sql_field->flags & NOT_NULL_FLAG) &&
2618
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
2619
    {
2620
      /*
2621
        An error should be reported if:
2622
          - NO_ZERO_DATE SQL mode is active;
2623
          - there is no explicit DEFAULT clause (default column value);
2624
          - this is a TIMESTAMP column;
2625
          - the column is not NULL;
2626
          - this is not the DEFAULT CURRENT_TIMESTAMP column.
2627
2628
        In other words, an error should be reported if
2629
          - NO_ZERO_DATE SQL mode is active;
2630
          - the column definition is equivalent to
2631
            'column_name TIMESTAMP DEFAULT 0'.
2632
      */
2633
2634
      my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2635
      DBUG_RETURN(TRUE);
2636
    }
2637
  }
2638
2639
  DBUG_RETURN(FALSE);
2640
}
2641
2642
2643
/*
2644
  Set table default charset, if not set
2645
2646
  SYNOPSIS
2647
    set_table_default_charset()
2648
    create_info        Table create information
2649
2650
  DESCRIPTION
2651
    If the table character set was not given explicitely,
2652
    let's fetch the database default character set and
2653
    apply it to the table.
2654
*/
2655
2656
static void set_table_default_charset(THD *thd,
2657
				      HA_CREATE_INFO *create_info, char *db)
2658
{
2659
  /*
2660
    If the table character set was not given explicitly,
2661
    let's fetch the database default character set and
2662
    apply it to the table.
2663
  */
2664
  if (!create_info->default_table_charset)
2665
  {
2666
    HA_CREATE_INFO db_info;
2667
2668
    load_db_opt_by_name(thd, db, &db_info);
2669
2670
    create_info->default_table_charset= db_info.default_table_charset;
2671
  }
2672
}
2673
2674
2675
/*
2676
  Extend long VARCHAR fields to blob & prepare field if it's a blob
2677
2678
  SYNOPSIS
2679
    prepare_blob_field()
2680
    sql_field		Field to check
2681
2682
  RETURN
2683
    0	ok
2684
    1	Error (sql_field can't be converted to blob)
2685
        In this case the error is given
2686
*/
2687
2688
static bool prepare_blob_field(THD *thd, Create_field *sql_field)
2689
{
2690
  DBUG_ENTER("prepare_blob_field");
2691
2692
  if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
2693
      !(sql_field->flags & BLOB_FLAG))
2694
  {
2695
    my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
2696
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
2697
    DBUG_RETURN(1);
2698
  }
2699
    
2700
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
2701
  {
2702
    if (sql_field->sql_type == MYSQL_TYPE_BLOB)
2703
    {
2704
      /* The user has given a length to the blob column */
2705
      sql_field->sql_type= get_blob_type_from_length(sql_field->length);
2706
      sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
2707
    }
2708
    sql_field->length= 0;
2709
  }
2710
  DBUG_RETURN(0);
2711
}
2712
2713
2714
/*
2715
  Preparation of Create_field for SP function return values.
2716
  Based on code used in the inner loop of mysql_prepare_create_table()
2717
  above.
2718
2719
  SYNOPSIS
2720
    sp_prepare_create_field()
2721
    thd			Thread object
2722
    sql_field		Field to prepare
2723
2724
  DESCRIPTION
2725
    Prepares the field structures for field creation.
2726
2727
*/
2728
2729
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
2730
{
2731
  if (sql_field->sql_type == MYSQL_TYPE_SET ||
2732
      sql_field->sql_type == MYSQL_TYPE_ENUM)
2733
  {
2734
    uint32 field_length, dummy;
2735
    if (sql_field->sql_type == MYSQL_TYPE_SET)
2736
    {
2737
      calculate_interval_lengths(sql_field->charset,
2738
                                 sql_field->interval, &dummy, 
2739
                                 &field_length);
2740
      sql_field->length= field_length + 
2741
                         (sql_field->interval->count - 1);
2742
    }
2743
    else /* MYSQL_TYPE_ENUM */
2744
    {
2745
      calculate_interval_lengths(sql_field->charset,
2746
                                 sql_field->interval,
2747
                                 &field_length, &dummy);
2748
      sql_field->length= field_length;
2749
    }
2750
    set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
2751
  }
2752
2753
  if (sql_field->sql_type == MYSQL_TYPE_BIT)
2754
  {
2755
    sql_field->pack_flag= FIELDFLAG_NUMBER |
2756
                          FIELDFLAG_TREAT_BIT_AS_CHAR;
2757
  }
2758
  sql_field->create_length_to_internal_length();
2759
  DBUG_ASSERT(sql_field->def == 0);
2760
  /* Can't go wrong as sql_field->def is not defined */
2761
  (void) prepare_blob_field(thd, sql_field);
2762
}
2763
2764
2765
/*
2766
  Create a table
2767
2768
  SYNOPSIS
2769
    mysql_create_table_no_lock()
2770
    thd			Thread object
2771
    db			Database
2772
    table_name		Table name
2773
    create_info	        Create information (like MAX_ROWS)
2774
    fields		List of fields to create
2775
    keys		List of keys to create
2776
    internal_tmp_table  Set to 1 if this is an internal temporary table
2777
			(From ALTER TABLE)
2778
    select_field_count  
2779
2780
  DESCRIPTION
2781
    If one creates a temporary table, this is automatically opened
2782
2783
    Note that this function assumes that caller already have taken
2784
    name-lock on table being created or used some other way to ensure
2785
    that concurrent operations won't intervene. mysql_create_table()
2786
    is a wrapper that can be used for this.
2787
2788
    no_log is needed for the case of CREATE ... SELECT,
2789
    as the logging will be done later in sql_insert.cc
2790
    select_field_count is also used for CREATE ... SELECT,
2791
    and must be zero for standard create of table.
2792
2793
  RETURN VALUES
2794
    FALSE OK
2795
    TRUE  error
2796
*/
2797
2798
bool mysql_create_table_no_lock(THD *thd,
2799
                                const char *db, const char *table_name,
2800
                                HA_CREATE_INFO *create_info,
2801
                                Alter_info *alter_info,
2802
                                bool internal_tmp_table,
2803
                                uint select_field_count)
2804
{
2805
  char		path[FN_REFLEN];
2806
  uint          path_length;
2807
  const char	*alias;
2808
  uint		db_options, key_count;
2809
  KEY		*key_info_buffer;
2810
  handler	*file;
2811
  bool		error= TRUE;
2812
  DBUG_ENTER("mysql_create_table_no_lock");
2813
  DBUG_PRINT("enter", ("db: '%s'  table: '%s'  tmp: %d",
2814
                       db, table_name, internal_tmp_table));
2815
2816
 
2817
  /* Check for duplicate fields and check type of table to create */
2818
  if (!alter_info->create_list.elements)
2819
  {
2820
    my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
2821
               MYF(0));
2822
    DBUG_RETURN(TRUE);
2823
  }
2824
  if (check_engine(thd, table_name, create_info))
2825
    DBUG_RETURN(TRUE);
2826
  db_options= create_info->table_options;
2827
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
2828
    db_options|=HA_OPTION_PACK_RECORD;
2829
  alias= table_case_name(create_info, table_name);
2830
  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
2831
                              create_info->db_type)))
2832
  {
2833
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
2834
    DBUG_RETURN(TRUE);
2835
  }
2836
2837
  set_table_default_charset(thd, create_info, (char*) db);
2838
2839
  if (mysql_prepare_create_table(thd, create_info, alter_info,
2840
                                 internal_tmp_table,
2841
                                 &db_options, file,
2842
			  &key_info_buffer, &key_count,
2843
			  select_field_count))
2844
    goto err;
2845
2846
      /* Check if table exists */
2847
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2848
  {
2849
    path_length= build_tmptable_filename(thd, path, sizeof(path));
2850
    create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
2851
  }
2852
  else  
2853
  {
2854
 #ifdef FN_DEVCHAR
2855
    /* check if the table name contains FN_DEVCHAR when defined */
2856
    if (strchr(alias, FN_DEVCHAR))
2857
    {
2858
      my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
2859
      DBUG_RETURN(TRUE);
2860
    }
2861
#endif
2862
    path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
2863
                                      internal_tmp_table ? FN_IS_TMP : 0);
2864
  }
2865
2866
  /* Check if table already exists */
2867
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
2868
      find_temporary_table(thd, db, table_name))
2869
  {
2870
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
2871
    {
2872
      create_info->table_existed= 1;		// Mark that table existed
2873
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
2874
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
2875
                          alias);
2876
      error= 0;
2877
      goto err;
2878
    }
2879
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
2880
    goto err;
2881
  }
2882
2883
  VOID(pthread_mutex_lock(&LOCK_open));
2884
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
2885
  {
2886
    if (!access(path,F_OK))
2887
    {
2888
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
2889
        goto warn;
2890
      my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
2891
      goto unlock_and_end;
2892
    }
2893
    /*
2894
      We don't assert here, but check the result, because the table could be
2895
      in the table definition cache and in the same time the .frm could be
2896
      missing from the disk, in case of manual intervention which deletes
2897
      the .frm file. The user has to use FLUSH TABLES; to clear the cache.
2898
      Then she could create the table. This case is pretty obscure and
2899
      therefore we don't introduce a new error message only for it.
2900
    */
2901
    if (get_cached_table_share(db, alias))
2902
    {
2903
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2904
      goto unlock_and_end;
2905
    }
2906
  }
2907
2908
  /*
2909
    Check that table with given name does not already
2910
    exist in any storage engine. In such a case it should
2911
    be discovered and the error ER_TABLE_EXISTS_ERROR be returned
2912
    unless user specified CREATE TABLE IF EXISTS
2913
    The LOCK_open mutex has been locked to make sure no
2914
    one else is attempting to discover the table. Since
2915
    it's not on disk as a frm file, no one could be using it!
2916
  */
2917
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
2918
  {
2919
    bool create_if_not_exists =
2920
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
2921
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
2922
    DBUG_PRINT("info", ("exists_in_engine: %u",retcode));
2923
    switch (retcode)
2924
    {
2925
      case HA_ERR_NO_SUCH_TABLE:
2926
        /* Normal case, no table exists. we can go and create it */
2927
        break;
2928
      case HA_ERR_TABLE_EXIST:
2929
        DBUG_PRINT("info", ("Table existed in handler"));
2930
2931
      if (create_if_not_exists)
2932
        goto warn;
2933
      my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
2934
      goto unlock_and_end;
2935
        break;
2936
      default:
2937
        DBUG_PRINT("info", ("error: %u from storage engine", retcode));
2938
        my_error(retcode, MYF(0),table_name);
2939
        goto unlock_and_end;
2940
    }
2941
  }
2942
2943
  thd_proc_info(thd, "creating table");
2944
  create_info->table_existed= 0;		// Mark that table is created
2945
2946
#ifdef HAVE_READLINK
2947
  if (test_if_data_home_dir(create_info->data_file_name))
2948
  {
2949
    my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
2950
    goto unlock_and_end;
2951
  }
2952
  if (test_if_data_home_dir(create_info->index_file_name))
2953
  {
2954
    my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
2955
    goto unlock_and_end;
2956
  }
2957
2958
  if (!my_use_symdir)
2959
#endif /* HAVE_READLINK */
2960
  {
2961
    if (create_info->data_file_name)
2962
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
2963
                   "DATA DIRECTORY option ignored");
2964
    if (create_info->index_file_name)
2965
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
2966
                   "INDEX DIRECTORY option ignored");
2967
    create_info->data_file_name= create_info->index_file_name= 0;
2968
  }
2969
  create_info->table_options=db_options;
2970
2971
  path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
2972
  if (rea_create_table(thd, path, db, table_name,
2973
                       create_info, alter_info->create_list,
2974
                       key_count, key_info_buffer, file))
2975
    goto unlock_and_end;
2976
2977
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2978
  {
2979
    /* Open table and put in temporary table list */
2980
    if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
2981
    {
2982
      (void) rm_temporary_table(create_info->db_type, path, false);
2983
      goto unlock_and_end;
2984
    }
2985
    thd->thread_specific_used= TRUE;
2986
  }
2987
2988
  /*
2989
    Don't write statement if:
2990
    - It is an internal temporary table,
2991
    - Row-based logging is used and it we are creating a temporary table, or
2992
    - The binary log is not open.
2993
    Otherwise, the statement shall be binlogged.
2994
   */
2995
  if (!internal_tmp_table &&
2996
      (!thd->current_stmt_binlog_row_based ||
2997
       (thd->current_stmt_binlog_row_based &&
2998
        !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
2999
    write_bin_log(thd, TRUE, thd->query, thd->query_length);
3000
  error= FALSE;
3001
unlock_and_end:
3002
  VOID(pthread_mutex_unlock(&LOCK_open));
3003
3004
err:
3005
  thd_proc_info(thd, "After create");
3006
  delete file;
3007
  DBUG_RETURN(error);
3008
3009
warn:
3010
  error= FALSE;
3011
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3012
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
3013
                      alias);
3014
  create_info->table_existed= 1;		// Mark that table existed
3015
  goto unlock_and_end;
3016
}
3017
3018
3019
/*
3020
  Database locking aware wrapper for mysql_create_table_no_lock(),
3021
*/
3022
3023
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
3024
                        HA_CREATE_INFO *create_info,
3025
                        Alter_info *alter_info,
3026
                        bool internal_tmp_table,
3027
                        uint select_field_count)
3028
{
3029
  TABLE *name_lock= 0;
3030
  bool result;
3031
  DBUG_ENTER("mysql_create_table");
3032
3033
  /* Wait for any database locks */
3034
  pthread_mutex_lock(&LOCK_lock_db);
3035
  while (!thd->killed &&
3036
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
3037
  {
3038
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
3039
    pthread_mutex_lock(&LOCK_lock_db);
3040
  }
3041
3042
  if (thd->killed)
3043
  {
3044
    pthread_mutex_unlock(&LOCK_lock_db);
3045
    DBUG_RETURN(TRUE);
3046
  }
3047
  creating_table++;
3048
  pthread_mutex_unlock(&LOCK_lock_db);
3049
3050
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
3051
  {
3052
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
3053
    {
3054
      result= TRUE;
3055
      goto unlock;
3056
    }
3057
    if (!name_lock)
3058
    {
3059
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
3060
      {
3061
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3062
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
3063
                            table_name);
3064
        create_info->table_existed= 1;
3065
        result= FALSE;
3066
      }
3067
      else
3068
      {
3069
        my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
3070
        result= TRUE;
3071
      }
3072
      goto unlock;
3073
    }
3074
  }
3075
3076
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
3077
                                     alter_info,
3078
                                     internal_tmp_table,
3079
                                     select_field_count);
3080
3081
unlock:
3082
  if (name_lock)
3083
  {
3084
    pthread_mutex_lock(&LOCK_open);
3085
    unlink_open_table(thd, name_lock, FALSE);
3086
    pthread_mutex_unlock(&LOCK_open);
3087
  }
3088
  pthread_mutex_lock(&LOCK_lock_db);
3089
  if (!--creating_table && creating_database)
3090
    pthread_cond_signal(&COND_refresh);
3091
  pthread_mutex_unlock(&LOCK_lock_db);
3092
  DBUG_RETURN(result);
3093
}
3094
3095
3096
/*
3097
** Give the key name after the first field with an optional '_#' after
3098
**/
3099
3100
static bool
3101
check_if_keyname_exists(const char *name, KEY *start, KEY *end)
3102
{
3103
  for (KEY *key=start ; key != end ; key++)
3104
    if (!my_strcasecmp(system_charset_info,name,key->name))
3105
      return 1;
3106
  return 0;
3107
}
3108
3109
3110
static char *
3111
make_unique_key_name(const char *field_name,KEY *start,KEY *end)
3112
{
3113
  char buff[MAX_FIELD_NAME],*buff_end;
3114
3115
  if (!check_if_keyname_exists(field_name,start,end) &&
3116
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
3117
    return (char*) field_name;			// Use fieldname
3118
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
3119
3120
  /*
3121
    Only 3 chars + '\0' left, so need to limit to 2 digit
3122
    This is ok as we can't have more than 100 keys anyway
3123
  */
3124
  for (uint i=2 ; i< 100; i++)
3125
  {
3126
    *buff_end= '_';
3127
    int10_to_str(i, buff_end+1, 10);
3128
    if (!check_if_keyname_exists(buff,start,end))
3129
      return sql_strdup(buff);
3130
  }
3131
  return (char*) "not_specified";		// Should never happen
3132
}
3133
3134
3135
/****************************************************************************
3136
** Alter a table definition
3137
****************************************************************************/
3138
3139
3140
/*
3141
  Rename a table.
3142
3143
  SYNOPSIS
3144
    mysql_rename_table()
3145
      base                      The handlerton handle.
3146
      old_db                    The old database name.
3147
      old_name                  The old table name.
3148
      new_db                    The new database name.
3149
      new_name                  The new table name.
3150
      flags                     flags for build_table_filename().
3151
                                FN_FROM_IS_TMP old_name is temporary.
3152
                                FN_TO_IS_TMP   new_name is temporary.
3153
                                NO_FRM_RENAME  Don't rename the FRM file
3154
                                but only the table in the storage engine.
3155
3156
  RETURN
3157
    FALSE   OK
3158
    TRUE    Error
3159
*/
3160
3161
bool
3162
mysql_rename_table(handlerton *base, const char *old_db,
3163
                   const char *old_name, const char *new_db,
3164
                   const char *new_name, uint flags)
3165
{
3166
  THD *thd= current_thd;
3167
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
3168
  char *from_base= from, *to_base= to;
3169
  char tmp_name[NAME_LEN+1];
3170
  handler *file;
3171
  int error=0;
3172
  DBUG_ENTER("mysql_rename_table");
3173
  DBUG_PRINT("enter", ("old: '%s'.'%s'  new: '%s'.'%s'",
3174
                       old_db, old_name, new_db, new_name));
3175
3176
  file= (base == NULL ? 0 :
3177
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
3178
3179
  build_table_filename(from, sizeof(from), old_db, old_name, "",
3180
                       flags & FN_FROM_IS_TMP);
3181
  build_table_filename(to, sizeof(to), new_db, new_name, "",
3182
                       flags & FN_TO_IS_TMP);
3183
3184
  /*
3185
    If lower_case_table_names == 2 (case-preserving but case-insensitive
3186
    file system) and the storage is not HA_FILE_BASED, we need to provide
3187
    a lowercase file name, but we leave the .frm in mixed case.
3188
   */
3189
  if (lower_case_table_names == 2 && file &&
3190
      !(file->ha_table_flags() & HA_FILE_BASED))
3191
  {
3192
    strmov(tmp_name, old_name);
3193
    my_casedn_str(files_charset_info, tmp_name);
3194
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
3195
                         flags & FN_FROM_IS_TMP);
3196
    from_base= lc_from;
3197
3198
    strmov(tmp_name, new_name);
3199
    my_casedn_str(files_charset_info, tmp_name);
3200
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
3201
                         flags & FN_TO_IS_TMP);
3202
    to_base= lc_to;
3203
  }
3204
  if (!file || !(error=file->ha_rename_table(from_base, to_base)))
3205
  {
3206
    if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
3207
    {
3208
      error=my_errno;
3209
      /* Restore old file name */
3210
      if (file)
3211
        file->ha_rename_table(to_base, from_base);
3212
    }
3213
  }
3214
  delete file;
3215
  if (error == HA_ERR_WRONG_COMMAND)
3216
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
3217
  else if (error)
3218
    my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
3219
  DBUG_RETURN(error != 0);
3220
}
3221
3222
3223
/*
3224
  Force all other threads to stop using the table
3225
3226
  SYNOPSIS
3227
    wait_while_table_is_used()
3228
    thd			Thread handler
3229
    table		Table to remove from cache
3230
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
3231
                        HA_EXTRA_FORCE_REOPEN if table is not be used
3232
                        HA_EXTRA_PREPARE_FOR_RENAME if table is to be renamed
3233
  NOTES
3234
   When returning, the table will be unusable for other threads until
3235
   the table is closed.
3236
3237
  PREREQUISITES
3238
    Lock on LOCK_open
3239
    Win32 clients must also have a WRITE LOCK on the table !
3240
*/
3241
3242
void wait_while_table_is_used(THD *thd, TABLE *table,
3243
                              enum ha_extra_function function)
3244
{
3245
  DBUG_ENTER("wait_while_table_is_used");
3246
  DBUG_PRINT("enter", ("table: '%s'  share: 0x%lx  db_stat: %u  version: %lu",
3247
                       table->s->table_name.str, (ulong) table->s,
3248
                       table->db_stat, table->s->version));
3249
3250
  safe_mutex_assert_owner(&LOCK_open);
3251
3252
  VOID(table->file->extra(function));
3253
  /* Mark all tables that are in use as 'old' */
3254
  mysql_lock_abort(thd, table, TRUE);	/* end threads waiting on lock */
3255
3256
  /* Wait until all there are no other threads that has this table open */
3257
  remove_table_from_cache(thd, table->s->db.str,
3258
                          table->s->table_name.str,
3259
                          RTFC_WAIT_OTHER_THREAD_FLAG);
3260
  DBUG_VOID_RETURN;
3261
}
3262
3263
/*
3264
  Close a cached table
3265
3266
  SYNOPSIS
3267
    close_cached_table()
3268
    thd			Thread handler
3269
    table		Table to remove from cache
3270
3271
  NOTES
3272
    Function ends by signaling threads waiting for the table to try to
3273
    reopen the table.
3274
3275
  PREREQUISITES
3276
    Lock on LOCK_open
3277
    Win32 clients must also have a WRITE LOCK on the table !
3278
*/
3279
3280
void close_cached_table(THD *thd, TABLE *table)
3281
{
3282
  DBUG_ENTER("close_cached_table");
3283
3284
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3285
  /* Close lock if this is not got with LOCK TABLES */
3286
  if (thd->lock)
3287
  {
3288
    mysql_unlock_tables(thd, thd->lock);
3289
    thd->lock=0;			// Start locked threads
3290
  }
3291
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
3292
  unlink_open_table(thd, table, TRUE);
3293
3294
  /* When lock on LOCK_open is freed other threads can continue */
3295
  broadcast_refresh();
3296
  DBUG_VOID_RETURN;
3297
}
3298
3299
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
3300
			     const char* operator_name, const char* errmsg)
3301
3302
{
3303
  Protocol *protocol= thd->protocol;
3304
  protocol->prepare_for_resend();
3305
  protocol->store(table->alias, system_charset_info);
3306
  protocol->store((char*) operator_name, system_charset_info);
3307
  protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3308
  protocol->store(errmsg, system_charset_info);
3309
  thd->clear_error();
3310
  if (protocol->write())
3311
    return -1;
3312
  return 1;
3313
}
3314
3315
3316
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
3317
			      HA_CHECK_OPT *check_opt)
3318
{
3319
  int error= 0;
3320
  TABLE tmp_table, *table;
3321
  TABLE_SHARE *share;
3322
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
3323
  const char **ext;
15 by brian
Fix for stat, NETWARE removal
3324
  struct stat stat_info;
1 by brian
clean slate
3325
  DBUG_ENTER("prepare_for_repair");
3326
3327
  if (!(check_opt->sql_flags & TT_USEFRM))
3328
    DBUG_RETURN(0);
3329
3330
  if (!(table= table_list->table))		/* if open_ltable failed */
3331
  {
3332
    char key[MAX_DBKEY_LENGTH];
3333
    uint key_length;
3334
3335
    key_length= create_table_def_key(thd, key, table_list, 0);
3336
    pthread_mutex_lock(&LOCK_open);
3337
    if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
3338
                                  &error))))
3339
    {
3340
      pthread_mutex_unlock(&LOCK_open);
3341
      DBUG_RETURN(0);				// Can't open frm file
3342
    }
3343
3344
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
3345
    {
3346
      release_table_share(share, RELEASE_NORMAL);
3347
      pthread_mutex_unlock(&LOCK_open);
3348
      DBUG_RETURN(0);                           // Out of memory
3349
    }
3350
    table= &tmp_table;
3351
    pthread_mutex_unlock(&LOCK_open);
3352
  }
3353
3354
  /*
3355
    REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
3356
  */
3357
  if (table->s->tmp_table)
3358
  {
3359
    error= send_check_errmsg(thd, table_list, "repair",
3360
			     "Cannot repair temporary table from .frm file");
3361
    goto end;
3362
  }
3363
3364
  /*
3365
    User gave us USE_FRM which means that the header in the index file is
3366
    trashed.
3367
    In this case we will try to fix the table the following way:
3368
    - Rename the data file to a temporary name
3369
    - Truncate the table
3370
    - Replace the new data file with the old one
3371
    - Run a normal repair using the new index file and the old data file
3372
  */
3373
3374
  /*
3375
    Check if this is a table type that stores index and data separately,
3376
    like ISAM or MyISAM. We assume fixed order of engine file name
3377
    extentions array. First element of engine file name extentions array
3378
    is meta/index file extention. Second element - data file extention. 
3379
  */
3380
  ext= table->file->bas_ext();
3381
  if (!ext[0] || !ext[1])
3382
    goto end;					// No data file
3383
3384
  // Name of data file
3385
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
15 by brian
Fix for stat, NETWARE removal
3386
  if (stat(from, &stat_info))
1 by brian
clean slate
3387
    goto end;				// Can't use USE_FRM flag
3388
3389
  my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
3390
	      from, current_pid, thd->thread_id);
3391
3392
  /* If we could open the table, close it */
3393
  if (table_list->table)
3394
  {
3395
    pthread_mutex_lock(&LOCK_open);
3396
    close_cached_table(thd, table);
3397
    pthread_mutex_unlock(&LOCK_open);
3398
  }
3399
  if (lock_and_wait_for_table_name(thd,table_list))
3400
  {
3401
    error= -1;
3402
    goto end;
3403
  }
3404
  if (my_rename(from, tmp, MYF(MY_WME)))
3405
  {
3406
    pthread_mutex_lock(&LOCK_open);
3407
    unlock_table_name(thd, table_list);
3408
    pthread_mutex_unlock(&LOCK_open);
3409
    error= send_check_errmsg(thd, table_list, "repair",
3410
			     "Failed renaming data file");
3411
    goto end;
3412
  }
3413
  if (mysql_truncate(thd, table_list, 1))
3414
  {
3415
    pthread_mutex_lock(&LOCK_open);
3416
    unlock_table_name(thd, table_list);
3417
    pthread_mutex_unlock(&LOCK_open);
3418
    error= send_check_errmsg(thd, table_list, "repair",
3419
			     "Failed generating table from .frm file");
3420
    goto end;
3421
  }
3422
  if (my_rename(tmp, from, MYF(MY_WME)))
3423
  {
3424
    pthread_mutex_lock(&LOCK_open);
3425
    unlock_table_name(thd, table_list);
3426
    pthread_mutex_unlock(&LOCK_open);
3427
    error= send_check_errmsg(thd, table_list, "repair",
3428
			     "Failed restoring .MYD file");
3429
    goto end;
3430
  }
3431
3432
  /*
3433
    Now we should be able to open the partially repaired table
3434
    to finish the repair in the handler later on.
3435
  */
3436
  pthread_mutex_lock(&LOCK_open);
3437
  if (reopen_name_locked_table(thd, table_list, TRUE))
3438
  {
3439
    unlock_table_name(thd, table_list);
3440
    pthread_mutex_unlock(&LOCK_open);
3441
    error= send_check_errmsg(thd, table_list, "repair",
3442
                             "Failed to open partially repaired table");
3443
    goto end;
3444
  }
3445
  pthread_mutex_unlock(&LOCK_open);
3446
3447
end:
3448
  if (table == &tmp_table)
3449
  {
3450
    pthread_mutex_lock(&LOCK_open);
3451
    closefrm(table, 1);				// Free allocated memory
3452
    pthread_mutex_unlock(&LOCK_open);
3453
  }
3454
  DBUG_RETURN(error);
3455
}
3456
3457
3458
3459
/*
3460
  RETURN VALUES
3461
    FALSE Message sent to net (admin operation went ok)
3462
    TRUE  Message should be sent by caller 
3463
          (admin operation or network communication failed)
3464
*/
3465
static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
3466
                              HA_CHECK_OPT* check_opt,
3467
                              const char *operator_name,
3468
                              thr_lock_type lock_type,
3469
                              bool open_for_modify,
3470
                              bool no_warnings_for_error,
3471
                              uint extra_open_options,
3472
                              int (*prepare_func)(THD *, TABLE_LIST *,
3473
                                                  HA_CHECK_OPT *),
3474
                              int (handler::*operator_func)(THD *,
3475
                                                            HA_CHECK_OPT *))
3476
{
3477
  TABLE_LIST *table;
3478
  SELECT_LEX *select= &thd->lex->select_lex;
3479
  List<Item> field_list;
3480
  Item *item;
3481
  Protocol *protocol= thd->protocol;
3482
  LEX *lex= thd->lex;
3483
  int result_code= 0;
3484
  CHARSET_INFO *cs= system_charset_info;
3485
  DBUG_ENTER("mysql_admin_table");
3486
3487
  if (end_active_trans(thd))
3488
    DBUG_RETURN(1);
3489
  field_list.push_back(item = new Item_empty_string("Table",
3490
                                                    NAME_CHAR_LEN * 2,
3491
                                                    cs));
3492
  item->maybe_null = 1;
3493
  field_list.push_back(item = new Item_empty_string("Op", 10, cs));
3494
  item->maybe_null = 1;
3495
  field_list.push_back(item = new Item_empty_string("Msg_type", 10, cs));
3496
  item->maybe_null = 1;
3497
  field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
3498
  item->maybe_null = 1;
3499
  if (protocol->send_fields(&field_list,
3500
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
3501
    DBUG_RETURN(TRUE);
3502
3503
  mysql_ha_rm_tables(thd, tables, FALSE);
3504
3505
  for (table= tables; table; table= table->next_local)
3506
  {
3507
    char table_name[NAME_LEN*2+2];
3508
    char* db = table->db;
3509
    bool fatal_error=0;
3510
3511
    DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
3512
    DBUG_PRINT("admin", ("extra_open_options: %u", extra_open_options));
3513
    strxmov(table_name, db, ".", table->table_name, NullS);
3514
    thd->open_options|= extra_open_options;
3515
    table->lock_type= lock_type;
3516
    /* open only one table from local list of command */
3517
    {
3518
      TABLE_LIST *save_next_global, *save_next_local;
3519
      save_next_global= table->next_global;
3520
      table->next_global= 0;
3521
      save_next_local= table->next_local;
3522
      table->next_local= 0;
3523
      select->table_list.first= (uchar*)table;
3524
      /*
3525
        Time zone tables and SP tables can be add to lex->query_tables list,
3526
        so it have to be prepared.
3527
        TODO: Investigate if we can put extra tables into argument instead of
3528
        using lex->query_tables
3529
      */
3530
      lex->query_tables= table;
3531
      lex->query_tables_last= &table->next_global;
3532
      lex->query_tables_own_last= 0;
3533
      thd->no_warnings_for_error= no_warnings_for_error;
3534
      table->required_type=FRMTYPE_TABLE;
3535
3536
      open_and_lock_tables(thd, table);
3537
      thd->no_warnings_for_error= 0;
3538
      table->next_global= save_next_global;
3539
      table->next_local= save_next_local;
3540
      thd->open_options&= ~extra_open_options;
3541
    }
3542
    DBUG_PRINT("admin", ("table: 0x%lx", (long) table->table));
3543
3544
    if (prepare_func)
3545
    {
3546
      DBUG_PRINT("admin", ("calling prepare_func"));
3547
      switch ((*prepare_func)(thd, table, check_opt)) {
3548
      case  1:           // error, message written to net
3549
        ha_autocommit_or_rollback(thd, 1);
3550
        end_trans(thd, ROLLBACK);
3551
        close_thread_tables(thd);
3552
        DBUG_PRINT("admin", ("simple error, admin next table"));
3553
        continue;
3554
      case -1:           // error, message could be written to net
3555
        /* purecov: begin inspected */
3556
        DBUG_PRINT("admin", ("severe error, stop"));
3557
        goto err;
3558
        /* purecov: end */
3559
      default:           // should be 0 otherwise
3560
        DBUG_PRINT("admin", ("prepare_func succeeded"));
3561
        ;
3562
      }
3563
    }
3564
3565
    /*
3566
      CHECK TABLE command is only command where VIEW allowed here and this
3567
      command use only temporary teble method for VIEWs resolving => there
3568
      can't be VIEW tree substitition of join view => if opening table
3569
      succeed then table->table will have real TABLE pointer as value (in
3570
      case of join view substitution table->table can be 0, but here it is
3571
      impossible)
3572
    */
3573
    if (!table->table)
3574
    {
3575
      DBUG_PRINT("admin", ("open table failed"));
3576
      if (!thd->warn_list.elements)
3577
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
3578
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
3579
      goto send_result;
3580
    }
3581
3582
    if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
3583
    {
3584
      /* purecov: begin inspected */
3585
      char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
3586
      uint length;
3587
      DBUG_PRINT("admin", ("sending error message"));
3588
      protocol->prepare_for_resend();
3589
      protocol->store(table_name, system_charset_info);
3590
      protocol->store(operator_name, system_charset_info);
3591
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3592
      length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
3593
                          table_name);
3594
      protocol->store(buff, length, system_charset_info);
3595
      ha_autocommit_or_rollback(thd, 0);
3596
      end_trans(thd, COMMIT);
3597
      close_thread_tables(thd);
3598
      lex->reset_query_tables_list(FALSE);
3599
      table->table=0;				// For query cache
3600
      if (protocol->write())
3601
	goto err;
3602
      continue;
3603
      /* purecov: end */
3604
    }
3605
3606
    /* Close all instances of the table to allow repair to rename files */
3607
    if (lock_type == TL_WRITE && table->table->s->version)
3608
    {
3609
      DBUG_PRINT("admin", ("removing table from cache"));
3610
      pthread_mutex_lock(&LOCK_open);
3611
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
3612
					      "Waiting to get writelock");
3613
      mysql_lock_abort(thd,table->table, TRUE);
3614
      remove_table_from_cache(thd, table->table->s->db.str,
3615
                              table->table->s->table_name.str,
3616
                              RTFC_WAIT_OTHER_THREAD_FLAG |
3617
                              RTFC_CHECK_KILLED_FLAG);
3618
      thd->exit_cond(old_message);
3619
      DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
3620
      if (thd->killed)
3621
	goto err;
3622
      open_for_modify= 0;
3623
    }
3624
3625
    if (table->table->s->crashed && operator_func == &handler::ha_check)
3626
    {
3627
      /* purecov: begin inspected */
3628
      DBUG_PRINT("admin", ("sending crashed warning"));
3629
      protocol->prepare_for_resend();
3630
      protocol->store(table_name, system_charset_info);
3631
      protocol->store(operator_name, system_charset_info);
3632
      protocol->store(STRING_WITH_LEN("warning"), system_charset_info);
3633
      protocol->store(STRING_WITH_LEN("Table is marked as crashed"),
3634
                      system_charset_info);
3635
      if (protocol->write())
3636
        goto err;
3637
      /* purecov: end */
3638
    }
3639
3640
    if (operator_func == &handler::ha_repair &&
3641
        !(check_opt->sql_flags & TT_USEFRM))
3642
    {
3643
      if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
3644
          (table->table->file->ha_check_for_upgrade(check_opt) ==
3645
           HA_ADMIN_NEEDS_ALTER))
3646
      {
3647
        DBUG_PRINT("admin", ("recreating table"));
3648
        ha_autocommit_or_rollback(thd, 1);
3649
        close_thread_tables(thd);
3650
        tmp_disable_binlog(thd); // binlogging is done by caller if wanted
3651
        result_code= mysql_recreate_table(thd, table);
3652
        reenable_binlog(thd);
3653
        /*
3654
          mysql_recreate_table() can push OK or ERROR.
3655
          Clear 'OK' status. If there is an error, keep it:
3656
          we will store the error message in a result set row 
3657
          and then clear.
3658
        */
3659
        if (thd->main_da.is_ok())
3660
          thd->main_da.reset_diagnostics_area();
3661
        goto send_result;
3662
      }
3663
    }
3664
3665
    DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
3666
    result_code = (table->table->file->*operator_func)(thd, check_opt);
3667
    DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
3668
3669
send_result:
3670
3671
    lex->cleanup_after_one_table_open();
3672
    thd->clear_error();  // these errors shouldn't get client
3673
    {
3674
      List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
3675
      MYSQL_ERROR *err;
3676
      while ((err= it++))
3677
      {
3678
        protocol->prepare_for_resend();
3679
        protocol->store(table_name, system_charset_info);
3680
        protocol->store((char*) operator_name, system_charset_info);
3681
        protocol->store(warning_level_names[err->level].str,
3682
                        warning_level_names[err->level].length,
3683
                        system_charset_info);
3684
        protocol->store(err->msg, system_charset_info);
3685
        if (protocol->write())
3686
          goto err;
3687
      }
3688
      mysql_reset_errors(thd, true);
3689
    }
3690
    protocol->prepare_for_resend();
3691
    protocol->store(table_name, system_charset_info);
3692
    protocol->store(operator_name, system_charset_info);
3693
3694
send_result_message:
3695
3696
    DBUG_PRINT("info", ("result_code: %d", result_code));
3697
    switch (result_code) {
3698
    case HA_ADMIN_NOT_IMPLEMENTED:
3699
      {
3700
	char buf[ERRMSGSIZE+20];
3701
	uint length=my_snprintf(buf, ERRMSGSIZE,
3702
				ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
3703
	protocol->store(STRING_WITH_LEN("note"), system_charset_info);
3704
	protocol->store(buf, length, system_charset_info);
3705
      }
3706
      break;
3707
3708
    case HA_ADMIN_NOT_BASE_TABLE:
3709
      {
3710
        char buf[ERRMSGSIZE+20];
3711
        uint length= my_snprintf(buf, ERRMSGSIZE,
3712
                                 ER(ER_BAD_TABLE_ERROR), table_name);
3713
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
3714
        protocol->store(buf, length, system_charset_info);
3715
      }
3716
      break;
3717
3718
    case HA_ADMIN_OK:
3719
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
3720
      protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
3721
      break;
3722
3723
    case HA_ADMIN_FAILED:
3724
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
3725
      protocol->store(STRING_WITH_LEN("Operation failed"),
3726
                      system_charset_info);
3727
      break;
3728
3729
    case HA_ADMIN_REJECT:
3730
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
3731
      protocol->store(STRING_WITH_LEN("Operation need committed state"),
3732
                      system_charset_info);
3733
      open_for_modify= FALSE;
3734
      break;
3735
3736
    case HA_ADMIN_ALREADY_DONE:
3737
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
3738
      protocol->store(STRING_WITH_LEN("Table is already up to date"),
3739
                      system_charset_info);
3740
      break;
3741
3742
    case HA_ADMIN_CORRUPT:
3743
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3744
      protocol->store(STRING_WITH_LEN("Corrupt"), system_charset_info);
3745
      fatal_error=1;
3746
      break;
3747
3748
    case HA_ADMIN_INVALID:
3749
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3750
      protocol->store(STRING_WITH_LEN("Invalid argument"),
3751
                      system_charset_info);
3752
      break;
3753
3754
    case HA_ADMIN_TRY_ALTER:
3755
    {
3756
      /*
3757
        This is currently used only by InnoDB. ha_innobase::optimize() answers
3758
        "try with alter", so here we close the table, do an ALTER TABLE,
3759
        reopen the table and do ha_innobase::analyze() on it.
3760
      */
3761
      ha_autocommit_or_rollback(thd, 0);
3762
      close_thread_tables(thd);
3763
      TABLE_LIST *save_next_local= table->next_local,
3764
                 *save_next_global= table->next_global;
3765
      table->next_local= table->next_global= 0;
3766
      tmp_disable_binlog(thd); // binlogging is done by caller if wanted
3767
      result_code= mysql_recreate_table(thd, table);
3768
      reenable_binlog(thd);
3769
      /*
3770
        mysql_recreate_table() can push OK or ERROR.
3771
        Clear 'OK' status. If there is an error, keep it:
3772
        we will store the error message in a result set row 
3773
        and then clear.
3774
      */
3775
      if (thd->main_da.is_ok())
3776
        thd->main_da.reset_diagnostics_area();
3777
      ha_autocommit_or_rollback(thd, 0);
3778
      close_thread_tables(thd);
3779
      if (!result_code) // recreation went ok
3780
      {
3781
        if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
3782
            ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
3783
          result_code= 0; // analyze went ok
3784
      }
3785
      if (result_code) // either mysql_recreate_table or analyze failed
3786
      {
3787
        DBUG_ASSERT(thd->is_error());
3788
        if (thd->is_error())
3789
        {
3790
          const char *err_msg= thd->main_da.message();
3791
          if (!thd->vio_ok())
3792
          {
3793
            sql_print_error(err_msg);
3794
          }
3795
          else
3796
          {
3797
            /* Hijack the row already in-progress. */
3798
            protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3799
            protocol->store(err_msg, system_charset_info);
3800
            (void)protocol->write();
3801
            /* Start off another row for HA_ADMIN_FAILED */
3802
            protocol->prepare_for_resend();
3803
            protocol->store(table_name, system_charset_info);
3804
            protocol->store(operator_name, system_charset_info);
3805
          }
3806
          thd->clear_error();
3807
        }
3808
      }
3809
      result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
3810
      table->next_local= save_next_local;
3811
      table->next_global= save_next_global;
3812
      goto send_result_message;
3813
    }
3814
    case HA_ADMIN_WRONG_CHECKSUM:
3815
    {
3816
      protocol->store(STRING_WITH_LEN("note"), system_charset_info);
3817
      protocol->store(ER(ER_VIEW_CHECKSUM), strlen(ER(ER_VIEW_CHECKSUM)),
3818
                      system_charset_info);
3819
      break;
3820
    }
3821
3822
    case HA_ADMIN_NEEDS_UPGRADE:
3823
    case HA_ADMIN_NEEDS_ALTER:
3824
    {
3825
      char buf[ERRMSGSIZE];
3826
      uint length;
3827
3828
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3829
      length=my_snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
3830
      protocol->store(buf, length, system_charset_info);
3831
      fatal_error=1;
3832
      break;
3833
    }
3834
3835
    default:				// Probably HA_ADMIN_INTERNAL_ERROR
3836
      {
3837
        char buf[ERRMSGSIZE+20];
3838
        uint length=my_snprintf(buf, ERRMSGSIZE,
3839
                                "Unknown - internal error %d during operation",
3840
                                result_code);
3841
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3842
        protocol->store(buf, length, system_charset_info);
3843
        fatal_error=1;
3844
        break;
3845
      }
3846
    }
3847
    if (table->table)
3848
    {
3849
      if (fatal_error)
3850
        table->table->s->version=0;               // Force close of table
3851
      else if (open_for_modify)
3852
      {
3853
        if (table->table->s->tmp_table)
3854
          table->table->file->info(HA_STATUS_CONST);
3855
        else
3856
        {
3857
          pthread_mutex_lock(&LOCK_open);
3858
          remove_table_from_cache(thd, table->table->s->db.str,
3859
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
3860
          pthread_mutex_unlock(&LOCK_open);
3861
        }
3862
      }
3863
    }
3864
    ha_autocommit_or_rollback(thd, 0);
3865
    end_trans(thd, COMMIT);
3866
    close_thread_tables(thd);
3867
    table->table=0;				// For query cache
3868
    if (protocol->write())
3869
      goto err;
3870
  }
3871
3872
  my_eof(thd);
3873
  DBUG_RETURN(FALSE);
3874
3875
err:
3876
  ha_autocommit_or_rollback(thd, 1);
3877
  end_trans(thd, ROLLBACK);
3878
  close_thread_tables(thd);			// Shouldn't be needed
3879
  if (table)
3880
    table->table=0;
3881
  DBUG_RETURN(TRUE);
3882
}
3883
3884
3885
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
3886
{
3887
  DBUG_ENTER("mysql_repair_table");
3888
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
3889
				"repair", TL_WRITE, 1,
3890
                                test(check_opt->sql_flags & TT_USEFRM),
3891
                                HA_OPEN_FOR_REPAIR,
3892
				&prepare_for_repair,
3893
				&handler::ha_repair));
3894
}
3895
3896
3897
bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
3898
{
3899
  DBUG_ENTER("mysql_optimize_table");
3900
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
3901
				"optimize", TL_WRITE, 1,0,0,0,
3902
				&handler::ha_optimize));
3903
}
3904
3905
3906
/*
3907
  Assigned specified indexes for a table into key cache
3908
3909
  SYNOPSIS
3910
    mysql_assign_to_keycache()
3911
    thd		Thread object
3912
    tables	Table list (one table only)
3913
3914
  RETURN VALUES
3915
   FALSE ok
3916
   TRUE  error
3917
*/
3918
3919
bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
3920
			     LEX_STRING *key_cache_name)
3921
{
3922
  HA_CHECK_OPT check_opt;
3923
  KEY_CACHE *key_cache;
3924
  DBUG_ENTER("mysql_assign_to_keycache");
3925
3926
  check_opt.init();
3927
  pthread_mutex_lock(&LOCK_global_system_variables);
3928
  if (!(key_cache= get_key_cache(key_cache_name)))
3929
  {
3930
    pthread_mutex_unlock(&LOCK_global_system_variables);
3931
    my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
3932
    DBUG_RETURN(TRUE);
3933
  }
3934
  pthread_mutex_unlock(&LOCK_global_system_variables);
3935
  check_opt.key_cache= key_cache;
3936
  DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
3937
				"assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
3938
				0, 0, &handler::assign_to_keycache));
3939
}
3940
3941
3942
/*
3943
  Reassign all tables assigned to a key cache to another key cache
3944
3945
  SYNOPSIS
3946
    reassign_keycache_tables()
3947
    thd		Thread object
3948
    src_cache	Reference to the key cache to clean up
3949
    dest_cache	New key cache
3950
3951
  NOTES
3952
    This is called when one sets a key cache size to zero, in which
3953
    case we have to move the tables associated to this key cache to
3954
    the "default" one.
3955
3956
    One has to ensure that one never calls this function while
3957
    some other thread is changing the key cache. This is assured by
3958
    the caller setting src_cache->in_init before calling this function.
3959
3960
    We don't delete the old key cache as there may still be pointers pointing
3961
    to it for a while after this function returns.
3962
3963
 RETURN VALUES
3964
    0	  ok
3965
*/
3966
3967
int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
3968
			     KEY_CACHE *dst_cache)
3969
{
3970
  DBUG_ENTER("reassign_keycache_tables");
3971
3972
  DBUG_ASSERT(src_cache != dst_cache);
3973
  DBUG_ASSERT(src_cache->in_init);
3974
  src_cache->param_buff_size= 0;		// Free key cache
3975
  ha_resize_key_cache(src_cache);
3976
  ha_change_key_cache(src_cache, dst_cache);
3977
  DBUG_RETURN(0);
3978
}
3979
3980
3981
/*
3982
  Preload specified indexes for a table into key cache
3983
3984
  SYNOPSIS
3985
    mysql_preload_keys()
3986
    thd		Thread object
3987
    tables	Table list (one table only)
3988
3989
  RETURN VALUES
3990
    FALSE ok
3991
    TRUE  error
3992
*/
3993
3994
bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
3995
{
3996
  DBUG_ENTER("mysql_preload_keys");
3997
  /*
3998
    We cannot allow concurrent inserts. The storage engine reads
3999
    directly from the index file, bypassing the cache. It could read
4000
    outdated information if parallel inserts into cache blocks happen.
4001
  */
4002
   DBUG_RETURN(mysql_admin_table(thd, tables, 0,
4003
				"preload_keys", TL_READ_NO_INSERT, 0, 0, 0, 0,
4004
				&handler::preload_keys));
4005
}
4006
4007
4008
4009
/**
4010
  @brief          Create frm file based on I_S table
4011
4012
  @param[in]      thd                      thread handler
4013
  @param[in]      schema_table             I_S table           
4014
  @param[in]      dst_path                 path where frm should be created
4015
  @param[in]      create_info              Create info
4016
4017
  @return         Operation status
4018
    @retval       0                        success
4019
    @retval       1                        error
4020
*/
4021
4022
4023
bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
4024
                                  char *dst_path, HA_CREATE_INFO *create_info)
4025
{
4026
  HA_CREATE_INFO local_create_info;
4027
  Alter_info alter_info;
4028
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
4029
  uint keys= schema_table->table->s->keys;
4030
  uint db_options= 0;
4031
  DBUG_ENTER("mysql_create_like_schema_frm");
4032
4033
  bzero((char*) &local_create_info, sizeof(local_create_info));
4034
  local_create_info.db_type= schema_table->table->s->db_type();
4035
  local_create_info.row_type= schema_table->table->s->row_type;
4036
  local_create_info.default_table_charset=default_charset_info;
4037
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
4038
  schema_table->table->use_all_columns();
4039
  if (mysql_prepare_alter_table(thd, schema_table->table,
4040
                                &local_create_info, &alter_info))
4041
    DBUG_RETURN(1);
4042
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
4043
                                 tmp_table, &db_options,
4044
                                 schema_table->table->file,
4045
                                 &schema_table->table->s->key_info, &keys, 0))
4046
    DBUG_RETURN(1);
4047
  local_create_info.max_rows= 0;
4048
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
4049
                       &local_create_info, alter_info.create_list,
4050
                       keys, schema_table->table->s->key_info,
4051
                       schema_table->table->file))
4052
    DBUG_RETURN(1);
4053
  DBUG_RETURN(0);
4054
}
4055
4056
4057
/*
4058
  Create a table identical to the specified table
4059
4060
  SYNOPSIS
4061
    mysql_create_like_table()
4062
    thd		Thread object
4063
    table       Table list element for target table
4064
    src_table   Table list element for source table
4065
    create_info Create info
4066
4067
  RETURN VALUES
4068
    FALSE OK
4069
    TRUE  error
4070
*/
4071
4072
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
4073
                             HA_CREATE_INFO *create_info)
4074
{
4075
  TABLE *name_lock= 0;
4076
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
4077
  uint dst_path_length;
4078
  char *db= table->db;
4079
  char *table_name= table->table_name;
4080
  int  err;
4081
  bool res= TRUE;
4082
  uint not_used;
4083
  DBUG_ENTER("mysql_create_like_table");
4084
4085
4086
  /* CREATE TABLE ... LIKE is not allowed for views. */
4087
  src_table->required_type= FRMTYPE_TABLE;
4088
4089
  /*
4090
    By opening source table we guarantee that it exists and no concurrent
4091
    DDL operation will mess with it. Later we also take an exclusive
4092
    name-lock on target table name, which makes copying of .frm file,
4093
    call to ha_create_table() and binlogging atomic against concurrent DML
4094
    and DDL operations on target table. Thus by holding both these "locks"
4095
    we ensure that our statement is properly isolated from all concurrent
4096
    operations which matter.
4097
  */
4098
  if (open_tables(thd, &src_table, &not_used, 0))
4099
    DBUG_RETURN(TRUE);
4100
4101
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
4102
4103
  DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
4104
4105
  /* 
4106
    Check that destination tables does not exist. Note that its name
4107
    was already checked when it was added to the table list.
4108
  */
4109
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
4110
  {
4111
    if (find_temporary_table(thd, db, table_name))
4112
      goto table_exists;
4113
    dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
4114
    create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
4115
  }
4116
  else
4117
  {
4118
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
4119
      goto err;
4120
    if (!name_lock)
4121
      goto table_exists;
4122
    dst_path_length= build_table_filename(dst_path, sizeof(dst_path),
4123
                                          db, table_name, reg_ext, 0);
4124
    if (!access(dst_path, F_OK))
4125
      goto table_exists;
4126
  }
4127
4128
  DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
4129
4130
  /*
4131
    Create a new table by copying from source table
4132
4133
    Altough exclusive name-lock on target table protects us from concurrent
4134
    DML and DDL operations on it we still want to wrap .FRM creation and call
4135
    to ha_create_table() in critical section protected by LOCK_open in order
4136
    to provide minimal atomicity against operations which disregard name-locks,
4137
    like I_S implementation, for example. This is a temporary and should not
4138
    be copied. Instead we should fix our code to always honor name-locks.
4139
4140
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
4141
    during the call to ha_create_table(). See bug #28614 for more info.
4142
  */
4143
  VOID(pthread_mutex_lock(&LOCK_open));
4144
  if (src_table->schema_table)
4145
  {
4146
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
4147
    {
4148
      VOID(pthread_mutex_unlock(&LOCK_open));
4149
      goto err;
4150
    }
4151
  }
4152
  else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
4153
  {
4154
    if (my_errno == ENOENT)
4155
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
4156
    else
4157
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
4158
    VOID(pthread_mutex_unlock(&LOCK_open));
4159
    goto err;
4160
  }
4161
4162
  /*
4163
    As mysql_truncate don't work on a new table at this stage of
4164
    creation, instead create the table directly (for both normal
4165
    and temporary tables).
4166
  */
4167
  DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
4168
4169
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
4170
  if (thd->variables.keep_files_on_create)
4171
    create_info->options|= HA_CREATE_KEEP_FILES;
4172
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
4173
  VOID(pthread_mutex_unlock(&LOCK_open));
4174
4175
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
4176
  {
4177
    if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
4178
                                     OTM_OPEN))
4179
    {
4180
      (void) rm_temporary_table(create_info->db_type,
4181
				dst_path, false); /* purecov: inspected */
4182
      goto err;     /* purecov: inspected */
4183
    }
4184
  }
4185
  else if (err)
4186
  {
4187
    (void) quick_rm_table(create_info->db_type, db,
4188
			  table_name, 0); /* purecov: inspected */
4189
    goto err;	    /* purecov: inspected */
4190
  }
4191
4192
  DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
4193
4194
  /*
4195
    We have to write the query before we unlock the tables.
4196
  */
4197
  if (thd->current_stmt_binlog_row_based)
4198
  {
4199
    /*
4200
       Since temporary tables are not replicated under row-based
4201
       replication, CREATE TABLE ... LIKE ... needs special
4202
       treatement.  We have four cases to consider, according to the
4203
       following decision table:
4204
4205
           ==== ========= ========= ==============================
4206
           Case    Target    Source Write to binary log
4207
           ==== ========= ========= ==============================
4208
           1       normal    normal Original statement
4209
           2       normal temporary Generated statement
4210
           3    temporary    normal Nothing
4211
           4    temporary temporary Nothing
4212
           ==== ========= ========= ==============================
4213
    */
4214
    if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
4215
    {
4216
      if (src_table->table->s->tmp_table)               // Case 2
4217
      {
4218
        char buf[2048];
4219
        String query(buf, sizeof(buf), system_charset_info);
4220
        query.length(0);  // Have to zero it since constructor doesn't
4221
4222
4223
        /*
4224
          Here we open the destination table, on which we already have
4225
          name-lock. This is needed for store_create_info() to work.
4226
          The table will be closed by unlink_open_table() at the end
4227
          of this function.
4228
        */
4229
        table->table= name_lock;
4230
        VOID(pthread_mutex_lock(&LOCK_open));
4231
        if (reopen_name_locked_table(thd, table, FALSE))
4232
        {
4233
          VOID(pthread_mutex_unlock(&LOCK_open));
4234
          goto err;
4235
        }
4236
        VOID(pthread_mutex_unlock(&LOCK_open));
4237
4238
        IF_DBUG(int result=) store_create_info(thd, table, &query,
4239
                                               create_info);
4240
4241
        DBUG_ASSERT(result == 0); // store_create_info() always return 0
4242
        write_bin_log(thd, TRUE, query.ptr(), query.length());
4243
      }
4244
      else                                      // Case 1
4245
        write_bin_log(thd, TRUE, thd->query, thd->query_length);
4246
    }
4247
    /*
4248
      Case 3 and 4 does nothing under RBR
4249
    */
4250
  }
4251
  else
4252
    write_bin_log(thd, TRUE, thd->query, thd->query_length);
4253
4254
  res= FALSE;
4255
  goto err;
4256
4257
table_exists:
4258
  if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
4259
  {
4260
    char warn_buff[MYSQL_ERRMSG_SIZE];
4261
    my_snprintf(warn_buff, sizeof(warn_buff),
4262
		ER(ER_TABLE_EXISTS_ERROR), table_name);
4263
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4264
		 ER_TABLE_EXISTS_ERROR,warn_buff);
4265
    res= FALSE;
4266
  }
4267
  else
4268
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
4269
4270
err:
4271
  if (name_lock)
4272
  {
4273
    pthread_mutex_lock(&LOCK_open);
4274
    unlink_open_table(thd, name_lock, FALSE);
4275
    pthread_mutex_unlock(&LOCK_open);
4276
  }
4277
  DBUG_RETURN(res);
4278
}
4279
4280
4281
bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
4282
{
4283
  thr_lock_type lock_type = TL_READ_NO_INSERT;
4284
4285
  DBUG_ENTER("mysql_analyze_table");
4286
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
4287
				"analyze", lock_type, 1, 0, 0, 0,
4288
				&handler::ha_analyze));
4289
}
4290
4291
4292
bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
4293
{
4294
  thr_lock_type lock_type = TL_READ_NO_INSERT;
4295
4296
  DBUG_ENTER("mysql_check_table");
4297
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
4298
				"check", lock_type,
4299
				0, 0, HA_OPEN_FOR_REPAIR, 0,
4300
				&handler::ha_check));
4301
}
4302
4303
4304
/* table_list should contain just one table */
4305
static int
4306
mysql_discard_or_import_tablespace(THD *thd,
4307
                                   TABLE_LIST *table_list,
4308
                                   enum tablespace_op_type tablespace_op)
4309
{
4310
  TABLE *table;
4311
  my_bool discard;
4312
  int error;
4313
  DBUG_ENTER("mysql_discard_or_import_tablespace");
4314
4315
  /*
4316
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
4317
    ALTER TABLE
4318
  */
4319
4320
  thd_proc_info(thd, "discard_or_import_tablespace");
4321
4322
  discard= test(tablespace_op == DISCARD_TABLESPACE);
4323
4324
 /*
4325
   We set this flag so that ha_innobase::open and ::external_lock() do
4326
   not complain when we lock the table
4327
 */
4328
  thd->tablespace_op= TRUE;
4329
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
4330
  {
4331
    thd->tablespace_op=FALSE;
4332
    DBUG_RETURN(-1);
4333
  }
4334
4335
  error= table->file->ha_discard_or_import_tablespace(discard);
4336
4337
  thd_proc_info(thd, "end");
4338
4339
  if (error)
4340
    goto err;
4341
4342
  /* The ALTER TABLE is always in its own transaction */
4343
  error = ha_autocommit_or_rollback(thd, 0);
4344
  if (end_active_trans(thd))
4345
    error=1;
4346
  if (error)
4347
    goto err;
4348
  write_bin_log(thd, FALSE, thd->query, thd->query_length);
4349
4350
err:
4351
  ha_autocommit_or_rollback(thd, error);
4352
  thd->tablespace_op=FALSE;
4353
  
4354
  if (error == 0)
4355
  {
4356
    my_ok(thd);
4357
    DBUG_RETURN(0);
4358
  }
4359
4360
  table->file->print_error(error, MYF(0));
4361
    
4362
  DBUG_RETURN(-1);
4363
}
4364
4365
/**
4366
  Copy all changes detected by parser to the HA_ALTER_FLAGS
4367
*/
4368
4369
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
4370
{
4371
  uint flags= alter_info->flags;
4372
4373
  if (ALTER_ADD_COLUMN & flags)
4374
    *alter_flags|= HA_ADD_COLUMN;
4375
  if (ALTER_DROP_COLUMN & flags)
4376
    *alter_flags|= HA_DROP_COLUMN;
4377
  if (ALTER_RENAME & flags)
4378
    *alter_flags|= HA_RENAME_TABLE;
4379
  if (ALTER_CHANGE_COLUMN & flags)
4380
    *alter_flags|= HA_CHANGE_COLUMN;
4381
  if (ALTER_COLUMN_DEFAULT & flags)
4382
    *alter_flags|= HA_COLUMN_DEFAULT_VALUE;
4383
  if (ALTER_COLUMN_STORAGE & flags)
4384
    *alter_flags|= HA_COLUMN_STORAGE;
4385
  if (ALTER_COLUMN_FORMAT & flags)
4386
    *alter_flags|= HA_COLUMN_FORMAT;
4387
  if (ALTER_COLUMN_ORDER & flags)
4388
    *alter_flags|= HA_ALTER_COLUMN_ORDER;
4389
  if (ALTER_STORAGE & flags)
4390
    *alter_flags|= HA_ALTER_STORAGE;
4391
  if (ALTER_ROW_FORMAT & flags)
4392
    *alter_flags|= HA_ALTER_ROW_FORMAT;
4393
  if (ALTER_RECREATE & flags)
4394
    *alter_flags|= HA_RECREATE;
4395
  if (ALTER_FOREIGN_KEY & flags)
4396
    *alter_flags|= HA_ALTER_FOREIGN_KEY;
4397
}
4398
4399
4400
/**
4401
   @param       thd                Thread
4402
   @param       table              The original table.
4403
   @param       alter_info         Alter options, fields and keys for the new
4404
                                   table.
4405
   @param       create_info        Create options for the new table.
4406
   @param       order_num          Number of order list elements.
4407
   @param[out]  ha_alter_flags  Flags that indicate what will be changed
4408
   @param[out]  ha_alter_info      Data structures needed for on-line alter
4409
   @param[out]  table_changes      Information about particular change
4410
4411
   First argument 'table' contains information of the original
4412
   table, which includes all corresponding parts that the new
4413
   table has in arguments create_list, key_list and create_info.
4414
4415
   By comparing the changes between the original and new table
4416
   we can determine how much it has changed after ALTER TABLE
4417
   and whether we need to make a copy of the table, or just change
4418
   the .frm file.
4419
4420
   Mark any changes detected in the ha_alter_flags.
4421
4422
   If there are no data changes, but index changes, 'index_drop_buffer'
4423
   and/or 'index_add_buffer' are populated with offsets into
4424
   table->key_info or key_info_buffer respectively for the indexes
4425
   that need to be dropped and/or (re-)created.
4426
4427
   @retval TRUE  error
4428
   @retval FALSE success
4429
*/
4430
4431
static
4432
bool
4433
compare_tables(THD *thd,
4434
               TABLE *table,
4435
               Alter_info *alter_info,
4436
                           HA_CREATE_INFO *create_info,
4437
               uint order_num,
4438
               HA_ALTER_FLAGS *alter_flags,
4439
               HA_ALTER_INFO *ha_alter_info,
4440
               uint *table_changes)
4441
{
4442
  Field **f_ptr, *field;
4443
  uint table_changes_local= 0;
4444
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
4445
  Create_field *new_field;
4446
  KEY_PART_INFO *key_part;
4447
  KEY_PART_INFO *end;
4448
  /*
4449
    Remember if the new definition has new VARCHAR column;
4450
    create_info->varchar will be reset in mysql_prepare_create_table.
4451
  */
4452
  bool varchar= create_info->varchar;
4453
  DBUG_ENTER("compare_tables");
4454
4455
  {
4456
    /*
4457
      Create a copy of alter_info.
4458
      To compare the new and old table definitions, we need to "prepare"
4459
      the new definition - transform it from parser output to a format
4460
      that describes the final table layout (all column defaults are
4461
      initialized, duplicate columns are removed). This is done by
4462
      mysql_prepare_create_table.  Unfortunately,
4463
      mysql_prepare_create_table performs its transformations
4464
      "in-place", that is, modifies the argument.  Since we would
4465
      like to keep compare_tables() idempotent (not altering any
4466
      of the arguments) we create a copy of alter_info here and
4467
      pass it to mysql_prepare_create_table, then use the result
4468
      to evaluate possibility of fast ALTER TABLE, and then
4469
      destroy the copy.
4470
    */
4471
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
4472
    THD *thd= table->in_use;
4473
    uint db_options= 0; /* not used */
4474
    /* Create the prepared information. */
4475
    if (mysql_prepare_create_table(thd, create_info,
4476
                                   &tmp_alter_info,
4477
                                   (table->s->tmp_table != NO_TMP_TABLE),
4478
                                   &db_options,
4479
                                   table->file,
4480
                                   &ha_alter_info->key_info_buffer,
4481
                                   &ha_alter_info->key_count,
4482
                                   /* select_field_count */ 0))
4483
      DBUG_RETURN(TRUE);
4484
    /* Allocate result buffers. */
4485
    if (! (ha_alter_info->index_drop_buffer=
4486
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
4487
        ! (ha_alter_info->index_add_buffer=
4488
           (uint*) thd->alloc(sizeof(uint) *
4489
                              tmp_alter_info.key_list.elements)))
4490
      DBUG_RETURN(TRUE);
4491
  }
4492
  /*
4493
    First we setup ha_alter_flags based on what was detected
4494
    by parser
4495
  */
4496
  setup_ha_alter_flags(alter_info, alter_flags);
4497
4498
#ifndef DBUG_OFF
4499
  {
4500
    char dbug_string[HA_MAX_ALTER_FLAGS+1];
4501
    alter_flags->print(dbug_string);
4502
    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
4503
  }
4504
#endif
4505
4506
  /*
4507
    Some very basic checks. If number of fields changes, or the
4508
    handler, we need to run full ALTER TABLE. In the future
4509
    new fields can be added and old dropped without copy, but
4510
    not yet.
4511
4512
    Test also that engine was not given during ALTER TABLE, or
4513
    we are force to run regular alter table (copy).
4514
    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
4515
4516
    For the following ones we also want to run regular alter table:
4517
    ALTER TABLE tbl_name ORDER BY ..
4518
    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
4519
4520
    At the moment we can't handle altering temporary tables without a copy.
4521
    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
4522
    In that case we always do full copy.
4523
4524
    There was a bug prior to mysql-4.0.25. Number of null fields was
4525
    calculated incorrectly. As a result frm and data files gets out of
4526
    sync after fast alter table. There is no way to determine by which
4527
    mysql version (in 4.0 and 4.1 branches) table was created, thus we
4528
    disable fast alter table for all tables created by mysql versions
4529
    prior to 5.0 branch.
4530
    See BUG#6236.
4531
  */
4532
  if (table->s->fields != alter_info->create_list.elements ||
4533
      table->s->db_type() != create_info->db_type ||
4534
      table->s->tmp_table ||
4535
      create_info->used_fields & HA_CREATE_USED_ENGINE ||
4536
      create_info->used_fields & HA_CREATE_USED_CHARSET ||
4537
      create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
4538
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
4539
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
4540
      order_num ||
4541
      !table->s->mysql_version ||
4542
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
4543
  {
4544
    *table_changes= IS_EQUAL_NO;
4545
    /*
4546
      Check what has changed and set alter_flags
4547
    */
4548
    if (table->s->fields < alter_info->create_list.elements)
4549
      *alter_flags|= HA_ADD_COLUMN;
4550
    else if (table->s->fields > alter_info->create_list.elements)
4551
      *alter_flags|= HA_DROP_COLUMN;
4552
    if (create_info->db_type != table->s->db_type() ||
4553
        create_info->used_fields & HA_CREATE_USED_ENGINE)
4554
      *alter_flags|= HA_ALTER_STORAGE_ENGINE;
4555
    if (create_info->used_fields & HA_CREATE_USED_CHARSET)
4556
      *alter_flags|= HA_CHANGE_CHARACTER_SET;
4557
    if (create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)
4558
      *alter_flags|= HA_SET_DEFAULT_CHARACTER_SET;
4559
    if (alter_info->flags & ALTER_RECREATE)
4560
      *alter_flags|= HA_RECREATE;
4561
    /* TODO check for ADD/DROP FOREIGN KEY */
4562
    if (alter_info->flags & ALTER_FOREIGN_KEY)
4563
      *alter_flags|=  HA_ALTER_FOREIGN_KEY;
4564
    if (!table->s->mysql_version ||
4565
        (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
4566
      *alter_flags|=  HA_ALTER_COLUMN_TYPE;
4567
  }
4568
  /*
4569
    Go through fields and check if the original ones are compatible
4570
    with new table.
4571
  */
4572
  for (f_ptr= table->field, new_field= new_field_it++;
4573
       (new_field && (field= *f_ptr));
4574
       f_ptr++, new_field= new_field_it++)
4575
  {
4576
    /* Make sure we have at least the default charset in use. */
4577
    if (!new_field->charset)
4578
      new_field->charset= create_info->default_table_charset;
4579
4580
    /* Don't pack rows in old tables if the user has requested this. */
4581
    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
4582
        (new_field->flags & BLOB_FLAG) ||
4583
        (new_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
4584
      create_info->table_options|= HA_OPTION_PACK_RECORD;
4585
4586
    /* Check how fields have been modified */
4587
    if (alter_info->flags & ALTER_CHANGE_COLUMN)
4588
    {
4589
      /* Evaluate changes bitmap and send to check_if_incompatible_data() */
4590
      if (!(table_changes_local= field->is_equal(new_field)))
4591
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
4592
4593
      /* Check if field was renamed */
4594
      field->flags&= ~FIELD_IS_RENAMED;
4595
      if (my_strcasecmp(system_charset_info,
4596
                        field->field_name,
4597
                        new_field->field_name))
4598
      {
4599
        field->flags|= FIELD_IS_RENAMED;
4600
        *alter_flags|= HA_ALTER_COLUMN_NAME;
4601
      }
4602
4603
      *table_changes&= table_changes_local;
4604
      if (table_changes_local == IS_EQUAL_PACK_LENGTH)
4605
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
4606
4607
      /* Check that NULL behavior is same for old and new fields */
4608
      if ((new_field->flags & NOT_NULL_FLAG) !=
4609
          (uint) (field->flags & NOT_NULL_FLAG))
4610
      {
4611
        *table_changes= IS_EQUAL_NO;
4612
        *alter_flags|= HA_ALTER_COLUMN_NULLABLE;
4613
      }
4614
    }
4615
4616
    /* Clear indexed marker */
4617
    field->flags&= ~FIELD_IN_ADD_INDEX;
4618
  }
4619
4620
  /*
4621
    Go through keys and check if the original ones are compatible
4622
    with new table.
4623
  */
4624
  KEY *table_key;
4625
  KEY *table_key_end= table->key_info + table->s->keys;
4626
  KEY *new_key;
4627
  KEY *new_key_end=
4628
       ha_alter_info->key_info_buffer + ha_alter_info->key_count;
4629
4630
  DBUG_PRINT("info", ("index count old: %d  new: %d",
4631
                      table->s->keys, ha_alter_info->key_count));
4632
  /*
4633
    Step through all keys of the old table and search matching new keys.
4634
  */
4635
  ha_alter_info->index_drop_count= 0;
4636
  ha_alter_info->index_add_count= 0;
4637
  for (table_key= table->key_info; table_key < table_key_end; table_key++)
4638
  {
4639
    KEY_PART_INFO *table_part;
4640
    KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
4641
    KEY_PART_INFO *new_part;
4642
4643
    /* Search a new key with the same name. */
4644
    for (new_key= ha_alter_info->key_info_buffer;
4645
         new_key < new_key_end;
4646
         new_key++)
4647
    {
4648
      if (! strcmp(table_key->name, new_key->name))
4649
        break;
4650
    }
4651
    if (new_key >= new_key_end)
4652
    {
4653
      /* Key not found. Add the offset of the key to the drop buffer. */
4654
      ha_alter_info->index_drop_buffer
4655
           [ha_alter_info->index_drop_count++]=
4656
           table_key - table->key_info;
4657
      if (table_key->flags & HA_NOSAME)
4658
      {
4659
        /* Unique key. Check for "PRIMARY". */
4660
        if (! my_strcasecmp(system_charset_info,
4661
                            table_key->name, primary_key_name))
4662
          *alter_flags|= HA_DROP_PK_INDEX;
4663
        else
4664
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
4665
      }
4666
      else
4667
        *alter_flags|= HA_DROP_INDEX;
4668
      *table_changes= IS_EQUAL_NO;
4669
      DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
4670
      continue;
4671
    }
4672
4673
    /* Check that the key types are compatible between old and new tables. */
4674
    if ((table_key->algorithm != new_key->algorithm) ||
4675
        ((table_key->flags & HA_KEYFLAG_MASK) !=
4676
         (new_key->flags & HA_KEYFLAG_MASK)) ||
4677
        (table_key->key_parts != new_key->key_parts))
4678
    {
4679
      if (table_key->flags & HA_NOSAME)
4680
      {
4681
        // Unique key. Check for "PRIMARY".
4682
        if (! my_strcasecmp(system_charset_info,
4683
                            table_key->name, primary_key_name))
4684
          *alter_flags|= HA_ALTER_PK_INDEX;
4685
        else
4686
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
4687
      }
4688
      else
4689
        *alter_flags|= HA_ALTER_INDEX;
4690
      goto index_changed;
4691
    }
4692
4693
    /*
4694
      Check that the key parts remain compatible between the old and
4695
      new tables.
4696
    */
4697
    for (table_part= table_key->key_part, new_part= new_key->key_part;
4698
         table_part < table_part_end;
4699
         table_part++, new_part++)
4700
    {
4701
      /*
4702
        Key definition has changed if we are using a different field or
4703
	if the used key part length is different. We know that the fields
4704
        did not change. Comparing field numbers is sufficient.
4705
      */
4706
      if ((table_part->length != new_part->length) ||
4707
          (table_part->fieldnr - 1 != new_part->fieldnr))
4708
      {
4709
        if (table_key->flags & HA_NOSAME)
4710
        {
4711
          /* Unique key. Check for "PRIMARY" */
4712
          if (! my_strcasecmp(system_charset_info,
4713
                              table_key->name, primary_key_name))
4714
            *alter_flags|= HA_ALTER_PK_INDEX;
4715
          else
4716
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
4717
        }
4718
        else
4719
          *alter_flags|= HA_ALTER_INDEX;
4720
        goto index_changed;
4721
      }
4722
    }
4723
    continue;
4724
4725
  index_changed:
4726
    /* Key modified. Add the offset of the key to both buffers. */
4727
    ha_alter_info->index_drop_buffer
4728
         [ha_alter_info->index_drop_count++]=
4729
         table_key - table->key_info;
4730
    ha_alter_info->index_add_buffer
4731
         [ha_alter_info->index_add_count++]=
4732
         new_key - ha_alter_info->key_info_buffer;
4733
    key_part= new_key->key_part;
4734
    end= key_part + new_key->key_parts;
4735
    for(; key_part != end; key_part++)
4736
    {
4737
      /* Mark field to be part of new key */
4738
      if ((field= table->field[key_part->fieldnr]))
4739
        field->flags|= FIELD_IN_ADD_INDEX;
4740
    }
4741
    *table_changes= IS_EQUAL_NO;
4742
    DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
4743
  }
4744
  /*end of for (; table_key < table_key_end;) */
4745
4746
  /*
4747
    Step through all keys of the new table and find matching old keys.
4748
  */
4749
  for (new_key= ha_alter_info->key_info_buffer;
4750
       new_key < new_key_end;
4751
       new_key++)
4752
  {
4753
    /* Search an old key with the same name. */
4754
    for (table_key= table->key_info; table_key < table_key_end; table_key++)
4755
    {
4756
      if (! strcmp(table_key->name, new_key->name))
4757
        break;
4758
    }
4759
    if (table_key >= table_key_end)
4760
    {
4761
      /* Key not found. Add the offset of the key to the add buffer. */
4762
      ha_alter_info->index_add_buffer
4763
           [ha_alter_info->index_add_count++]=
4764
           new_key - ha_alter_info->key_info_buffer;
4765
      key_part= new_key->key_part;
4766
      end= key_part + new_key->key_parts;
4767
      for(; key_part != end; key_part++)
4768
      {
4769
        /* Mark field to be part of new key */
4770
        if ((field= table->field[key_part->fieldnr]))
4771
          field->flags|= FIELD_IN_ADD_INDEX;
4772
      }
4773
      if (new_key->flags & HA_NOSAME)
4774
      {
4775
        /* Unique key. Check for "PRIMARY" */
4776
        if (! my_strcasecmp(system_charset_info,
4777
                            new_key->name, primary_key_name))
4778
          *alter_flags|= HA_ADD_PK_INDEX;
4779
        else
4780
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
4781
      }
4782
      else
4783
        *alter_flags|= HA_ADD_INDEX;
4784
      *table_changes= IS_EQUAL_NO;
4785
      DBUG_PRINT("info", ("index added: '%s'", new_key->name));
4786
    }
4787
  }
4788
#ifndef DBUG_OFF
4789
  {
4790
    char dbug_string[HA_MAX_ALTER_FLAGS+1];
4791
    alter_flags->print(dbug_string);
4792
    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
4793
  }
4794
#endif
4795
4796
  DBUG_RETURN(FALSE);
4797
}
4798
4799
4800
/*
4801
  Manages enabling/disabling of indexes for ALTER TABLE
4802
4803
  SYNOPSIS
4804
    alter_table_manage_keys()
4805
      table                  Target table
4806
      indexes_were_disabled  Whether the indexes of the from table
4807
                             were disabled
4808
      keys_onoff             ENABLE | DISABLE | LEAVE_AS_IS
4809
4810
  RETURN VALUES
4811
    FALSE  OK
4812
    TRUE   Error
4813
*/
4814
4815
static
4816
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
4817
                             enum enum_enable_or_disable keys_onoff)
4818
{
4819
  int error= 0;
4820
  DBUG_ENTER("alter_table_manage_keys");
4821
  DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
4822
             table, indexes_were_disabled, keys_onoff));
4823
4824
  switch (keys_onoff) {
4825
  case ENABLE:
4826
    error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4827
    break;
4828
  case LEAVE_AS_IS:
4829
    if (!indexes_were_disabled)
4830
      break;
4831
    /* fall-through: disabled indexes */
4832
  case DISABLE:
4833
    error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4834
  }
4835
4836
  if (error == HA_ERR_WRONG_COMMAND)
4837
  {
4838
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4839
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4840
                        table->s->table_name.str);
4841
    error= 0;
4842
  } else if (error)
4843
    table->file->print_error(error, MYF(0));
4844
4845
  DBUG_RETURN(error);
4846
}
4847
4848
int create_temporary_table(THD *thd,
4849
                           TABLE *table,
4850
                           char *new_db,
4851
                           char *tmp_name,
4852
                           HA_CREATE_INFO *create_info,
4853
                           Alter_info *alter_info,
4854
                           bool db_changed)
4855
{
4856
  int error;
4857
  char index_file[FN_REFLEN], data_file[FN_REFLEN];
4858
  handlerton *old_db_type, *new_db_type;
4859
  DBUG_ENTER("create_temporary_table");
4860
  old_db_type= table->s->db_type();
4861
  new_db_type= create_info->db_type;
4862
  /*
4863
    Handling of symlinked tables:
4864
    If no rename:
4865
      Create new data file and index file on the same disk as the
4866
      old data and index files.
4867
      Copy data.
4868
      Rename new data file over old data file and new index file over
4869
      old index file.
4870
      Symlinks are not changed.
4871
4872
   If rename:
4873
      Create new data file and index file on the same disk as the
4874
      old data and index files.  Create also symlinks to point at
4875
      the new tables.
4876
      Copy data.
4877
      At end, rename intermediate tables, and symlinks to intermediate
4878
      table, to final table name.
4879
      Remove old table and old symlinks
4880
4881
    If rename is made to another database:
4882
      Create new tables in new database.
4883
      Copy data.
4884
      Remove old table and symlinks.
4885
  */
4886
  if (db_changed)		// Ignore symlink if db changed
4887
  {
4888
    if (create_info->index_file_name)
4889
    {
4890
      /* Fix index_file_name to have 'tmp_name' as basename */
4891
      strmov(index_file, tmp_name);
4892
      create_info->index_file_name=fn_same(index_file,
4893
                                           create_info->index_file_name,
4894
                                           1);
4895
    }
4896
    if (create_info->data_file_name)
4897
    {
4898
      /* Fix data_file_name to have 'tmp_name' as basename */
4899
      strmov(data_file, tmp_name);
4900
      create_info->data_file_name=fn_same(data_file,
4901
                                          create_info->data_file_name,
4902
                                          1);
4903
    }
4904
  }
4905
  else
4906
    create_info->data_file_name=create_info->index_file_name=0;
4907
4908
  if (new_db_type == old_db_type)
4909
  {
4910
    /*
4911
       Table has not changed storage engine.
4912
       If STORAGE and TABLESPACE have not been changed than copy them
4913
       from the original table
4914
    */
4915
    if (!create_info->tablespace &&
4916
        table->s->tablespace &&
4917
        create_info->default_storage_media == HA_SM_DEFAULT)
4918
      create_info->tablespace= table->s->tablespace;
4919
    if (create_info->default_storage_media == HA_SM_DEFAULT)
4920
      create_info->default_storage_media= table->s->default_storage_media;
4921
   }
4922
4923
  /*
4924
    Create a table with a temporary name.
4925
    With create_info->frm_only == 1 this creates a .frm file only.
4926
    We don't log the statement, it will be logged later.
4927
  */
4928
  tmp_disable_binlog(thd);
4929
  error= mysql_create_table(thd, new_db, tmp_name,
4930
                            create_info, alter_info, 1, 0);
4931
  reenable_binlog(thd);
4932
4933
  DBUG_RETURN(error);
4934
}
4935
4936
/*
4937
  Create a temporary table that reflects what an alter table operation
4938
  will accomplish.
4939
4940
  SYNOPSIS
4941
    create_altered_table()
4942
      thd              Thread handle
4943
      table            The original table
4944
      create_info      Information from the parsing phase about new
4945
                       table properties.
4946
      alter_info       Lists of fields, keys to be changed, added
4947
                       or dropped.
4948
      db_change        Specifies if the table is moved to another database
4949
  RETURN
4950
    A temporary table with all changes
4951
    NULL if error
4952
  NOTES
4953
    The temporary table is created without storing it in any storage engine
4954
    and is opened only to get the table struct and frm file reference.
4955
*/
4956
TABLE *create_altered_table(THD *thd,
4957
                            TABLE *table,
4958
                            char *new_db,
4959
                            HA_CREATE_INFO *create_info,
4960
                            Alter_info *alter_info,
4961
                            bool db_change)
4962
{
4963
  int error;
4964
  HA_CREATE_INFO altered_create_info(*create_info);
4965
  TABLE *altered_table;
4966
  char tmp_name[80];
4967
  char path[FN_REFLEN];
4968
  DBUG_ENTER("create_altered_table");
4969
4970
  my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
4971
              tmp_file_prefix, current_pid, thd->thread_id);
4972
  /* Safety fix for InnoDB */
4973
  if (lower_case_table_names)
4974
    my_casedn_str(files_charset_info, tmp_name);
4975
  altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
4976
  altered_create_info.frm_only= 1;
4977
  if ((error= create_temporary_table(thd, table, new_db, tmp_name,
4978
                                     &altered_create_info,
4979
                                     alter_info, db_change)))
4980
  {
4981
    DBUG_PRINT("info", ("Error %u while creating temporary table", error));
4982
    DBUG_RETURN(NULL);
4983
  };
4984
4985
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4986
                       FN_IS_TMP);
4987
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
4988
                                      OTM_ALTER);
4989
  DBUG_RETURN(altered_table);
4990
4991
  DBUG_RETURN(NULL);
4992
}
4993
4994
4995
/*
4996
  Perform a fast or on-line alter table
4997
4998
  SYNOPSIS
4999
    mysql_fast_or_online_alter_table()
5000
      thd              Thread handle
5001
      table            The original table
5002
      altered_table    A temporary table showing how we will change table
5003
      create_info      Information from the parsing phase about new
5004
                       table properties.
5005
      alter_info       Storage place for data used during different phases
5006
      ha_alter_flags   Bitmask that shows what will be changed
5007
      keys_onoff       Specifies if keys are to be enabled/disabled
5008
  RETURN
5009
     0  OK
5010
    >0  An error occured during the on-line alter table operation
5011
    -1  Error when re-opening table
5012
  NOTES
5013
    If mysql_alter_table does not need to copy the table, it is
5014
    either a fast alter table where the storage engine does not
5015
    need to know about the change, only the frm will change,
5016
    or the storage engine supports performing the alter table
5017
    operation directly, on-line without mysql having to copy
5018
    the table.
5019
*/
5020
int mysql_fast_or_online_alter_table(THD *thd,
5021
                                     TABLE *table,
5022
                                     TABLE *altered_table,
5023
                                     HA_CREATE_INFO *create_info,
5024
                                     HA_ALTER_INFO *alter_info,
5025
                                     HA_ALTER_FLAGS *ha_alter_flags,
5026
                                     enum enum_enable_or_disable keys_onoff)
5027
{
5028
  int error= 0;
5029
  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER)?true:false;
5030
  TABLE *t_table;
5031
5032
  DBUG_ENTER(" mysql_fast_or_online_alter_table");
5033
  if (online)
5034
  {
5035
   /*
5036
      Tell the handler to prepare for the online alter
5037
    */
5038
    if ((error= table->file->alter_table_phase1(thd,
5039
                                                altered_table,
5040
                                                create_info,
5041
                                                alter_info,
5042
                                                ha_alter_flags)))
5043
    {
5044
      goto err;
5045
    }
5046
5047
    /*
5048
       Tell the storage engine to perform the online alter table
5049
       TODO: 
5050
       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
5051
       we need to wrap the next call with a DDL lock.
5052
     */
5053
    if ((error= table->file->alter_table_phase2(thd,
5054
                                                altered_table,
5055
                                                create_info,
5056
                                                alter_info,
5057
                                                ha_alter_flags)))
5058
    {
5059
      goto err;
5060
    }
5061
  }
5062
  /*
5063
    The final .frm file is already created as a temporary file
5064
    and will be renamed to the original table name.
5065
  */
5066
  VOID(pthread_mutex_lock(&LOCK_open));
5067
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5068
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
5069
                          keys_onoff);
5070
  close_data_files_and_morph_locks(thd,
5071
                                   table->pos_in_table_list->db,
5072
                                   table->pos_in_table_list->table_name);
5073
  if (mysql_rename_table(NULL,
5074
			 altered_table->s->db.str,
5075
                         altered_table->s->table_name.str,
5076
			 table->s->db.str,
5077
                         table->s->table_name.str, FN_FROM_IS_TMP))
5078
  {
5079
    error= 1;
5080
    VOID(pthread_mutex_unlock(&LOCK_open));
5081
    goto err;
5082
  }
5083
  broadcast_refresh();
5084
  VOID(pthread_mutex_unlock(&LOCK_open));
5085
5086
  /*
5087
    The ALTER TABLE is always in its own transaction.
5088
    Commit must not be called while LOCK_open is locked. It could call
5089
    wait_if_global_read_lock(), which could create a deadlock if called
5090
    with LOCK_open.
5091
  */
5092
  error= ha_autocommit_or_rollback(thd, 0);
5093
5094
  if (ha_commit(thd))
5095
    error=1;
5096
  if (error)
5097
    goto err;
5098
  if (online)
5099
  {
5100
    VOID(pthread_mutex_lock(&LOCK_open));
5101
    if (reopen_table(table))
5102
    {
5103
      error= -1;
5104
      goto err;
5105
    }
5106
    VOID(pthread_mutex_unlock(&LOCK_open));
5107
    t_table= table;
5108
5109
   /*
5110
      Tell the handler that the changed frm is on disk and table
5111
      has been re-opened
5112
   */
5113
    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
5114
    {
5115
      goto err;
5116
    }
5117
5118
    /*
5119
      We are going to reopen table down on the road, so we have to restore
5120
      state of the TABLE object which we used for obtaining of handler
5121
      object to make it suitable for reopening.
5122
    */
5123
    DBUG_ASSERT(t_table == table);
5124
    table->open_placeholder= 1;
5125
    VOID(pthread_mutex_lock(&LOCK_open));
5126
    close_handle_and_leave_table_as_lock(table);
5127
    VOID(pthread_mutex_unlock(&LOCK_open));
5128
  }
5129
5130
 err:
5131
  if (error)
5132
    DBUG_PRINT("info", ("Got error %u", error));
5133
  DBUG_RETURN(error);
5134
}
5135
5136
5137
/**
5138
  Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
5139
5140
  This function transforms parse output of ALTER TABLE - lists of
5141
  columns and keys to add, drop or modify into, essentially,
5142
  CREATE TABLE definition - a list of columns and keys of the new
5143
  table. While doing so, it also performs some (bug not all)
5144
  semantic checks.
5145
5146
  This function is invoked when we know that we're going to
5147
  perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
5148
  is not possible, perhaps because the ALTER statement contains
5149
  instructions that require change in table data, not only in
5150
  table definition or indexes.
5151
5152
  @param[in,out]  thd         thread handle. Used as a memory pool
5153
                              and source of environment information.
5154
  @param[in]      table       the source table, open and locked
5155
                              Used as an interface to the storage engine
5156
                              to acquire additional information about
5157
                              the original table.
5158
  @param[in,out]  create_info A blob with CREATE/ALTER TABLE
5159
                              parameters
5160
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
5161
                              Originally create_info was used only in
5162
                              CREATE TABLE and alter_info only in ALTER TABLE.
5163
                              But since ALTER might end-up doing CREATE,
5164
                              this distinction is gone and we just carry
5165
                              around two structures.
5166
5167
  @return
5168
    Fills various create_info members based on information retrieved
5169
    from the storage engine.
5170
    Sets create_info->varchar if the table has a VARCHAR column.
5171
    Prepares alter_info->create_list and alter_info->key_list with
5172
    columns and keys of the new table.
5173
  @retval TRUE   error, out of memory or a semantical error in ALTER
5174
                 TABLE instructions
5175
  @retval FALSE  success
5176
*/
5177
5178
static bool
5179
mysql_prepare_alter_table(THD *thd, TABLE *table,
5180
                          HA_CREATE_INFO *create_info,
5181
                          Alter_info *alter_info)
5182
{
5183
  /* New column definitions are added here */
5184
  List<Create_field> new_create_list;
5185
  /* New key definitions are added here */
5186
  List<Key> new_key_list;
5187
  List_iterator<Alter_drop> drop_it(alter_info->drop_list);
5188
  List_iterator<Create_field> def_it(alter_info->create_list);
5189
  List_iterator<Alter_column> alter_it(alter_info->alter_list);
5190
  List_iterator<Key> key_it(alter_info->key_list);
5191
  List_iterator<Create_field> find_it(new_create_list);
5192
  List_iterator<Create_field> field_it(new_create_list);
5193
  List<Key_part_spec> key_parts;
5194
  uint db_create_options= (table->s->db_create_options
5195
                           & ~(HA_OPTION_PACK_RECORD));
5196
  uint used_fields= create_info->used_fields;
5197
  KEY *key_info=table->key_info;
5198
  bool rc= TRUE;
5199
5200
  DBUG_ENTER("mysql_prepare_alter_table");
5201
5202
  create_info->varchar= FALSE;
5203
  /* Let new create options override the old ones */
5204
  if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
5205
    create_info->min_rows= table->s->min_rows;
5206
  if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
5207
    create_info->max_rows= table->s->max_rows;
5208
  if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
5209
    create_info->avg_row_length= table->s->avg_row_length;
5210
  if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
5211
    create_info->default_table_charset= table->s->table_charset;
5212
  if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
5213
    {
5214
    /* Table has an autoincrement, copy value to new table */
5215
    table->file->info(HA_STATUS_AUTO);
5216
    create_info->auto_increment_value= table->file->stats.auto_increment_value;
5217
  }
5218
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
5219
    create_info->key_block_size= table->s->key_block_size;
5220
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
5221
    create_info->transactional= table->s->transactional;
5222
5223
  restore_record(table, s->default_values);     // Empty record for DEFAULT
5224
  Create_field *def;
5225
5226
    /*
5227
    First collect all fields from table which isn't in drop_list
5228
    */
5229
  Field **f_ptr,*field;
5230
  for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
5231
    {
5232
    if (field->type() == MYSQL_TYPE_STRING)
5233
      create_info->varchar= TRUE;
5234
    /* Check if field should be dropped */
5235
    Alter_drop *drop;
5236
    drop_it.rewind();
5237
    while ((drop=drop_it++))
5238
    {
5239
      if (drop->type == Alter_drop::COLUMN &&
5240
	  !my_strcasecmp(system_charset_info,field->field_name, drop->name))
5241
    {
5242
	/* Reset auto_increment value if it was dropped */
5243
	if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
5244
	    !(used_fields & HA_CREATE_USED_AUTO))
5245
      {
5246
	  create_info->auto_increment_value=0;
5247
	  create_info->used_fields|=HA_CREATE_USED_AUTO;
5248
      }
5249
	break;
5250
    }
5251
  }
5252
    if (drop)
5253
      {
5254
      drop_it.remove();
5255
      continue;
5256
    }
5257
    /* Check if field is changed */
5258
    def_it.rewind();
5259
    while ((def=def_it++))
5260
    {
5261
      if (def->change &&
5262
	  !my_strcasecmp(system_charset_info,field->field_name, def->change))
5263
	break;
5264
    }
5265
    if (def)
5266
    {						// Field is changed
5267
      def->field=field;
5268
      if (!def->after)
5269
	{
5270
	new_create_list.push_back(def);
5271
	def_it.remove();
5272
	}
5273
      }
5274
      else
5275
      {
5276
      /*
5277
        This field was not dropped and not changed, add it to the list
5278
        for the new table.
5279
      */
5280
      def= new Create_field(field, field);
5281
      new_create_list.push_back(def);
5282
      alter_it.rewind();			// Change default if ALTER
5283
      Alter_column *alter;
5284
      while ((alter=alter_it++))
5285
        {
5286
	if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
5287
	  break;
5288
        }
5289
      if (alter)
5290
	{
5291
	if (def->sql_type == MYSQL_TYPE_BLOB)
5292
	{
5293
	  my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
5294
          goto err;
5295
	}
5296
	if ((def->def=alter->def))              // Use new default
5297
          def->flags&= ~NO_DEFAULT_VALUE_FLAG;
5298
        else
5299
          def->flags|= NO_DEFAULT_VALUE_FLAG;
5300
	alter_it.remove();
5301
      }
5302
    }
5303
  }
5304
  def_it.rewind();
5305
  while ((def=def_it++))			// Add new columns
5306
  {
5307
    if (def->change && ! def->field)
5308
    {
5309
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
5310
      goto err;
5311
    }
5312
      /*
5313
      Check that the DATE/DATETIME not null field we are going to add is
5314
      either has a default value or the '0000-00-00' is allowed by the
5315
      set sql mode.
5316
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
5317
      flag to allow ALTER TABLE only if the table to be altered is empty.
5318
      */
5319
    if ((def->sql_type == MYSQL_TYPE_DATE ||
5320
         def->sql_type == MYSQL_TYPE_NEWDATE ||
5321
         def->sql_type == MYSQL_TYPE_DATETIME) &&
5322
         !alter_info->datetime_field &&
5323
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
5324
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
5325
    {
5326
        alter_info->datetime_field= def;
5327
        alter_info->error_if_not_empty= TRUE;
5328
    }
5329
    if (!def->after)
5330
      new_create_list.push_back(def);
5331
    else if (def->after == first_keyword)
5332
      new_create_list.push_front(def);
5333
    else
5334
    {
5335
      Create_field *find;
5336
      find_it.rewind();
5337
      while ((find=find_it++))			// Add new columns
5338
      {
5339
	if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
5340
	  break;
5341
  }
5342
      if (!find)
5343
  {
5344
	my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
5345
    goto err;
5346
  }
5347
      find_it.after(def);			// Put element after this
5348
      /*
5349
        XXX: hack for Bug#28427.
5350
        If column order has changed, force OFFLINE ALTER TABLE
5351
        without querying engine capabilities.  If we ever have an
5352
        engine that supports online ALTER TABLE CHANGE COLUMN
5353
        <name> AFTER <name1> (Falcon?), this fix will effectively
5354
        disable the capability.
5355
        TODO: detect the situation in compare_tables, behave based
5356
        on engine capabilities.
5357
      */
5358
      if (alter_info->build_method == HA_BUILD_ONLINE)
5359
      {
5360
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
5361
        goto err;
5362
      }
5363
      alter_info->build_method= HA_BUILD_OFFLINE;
5364
    }
5365
  }
5366
  if (alter_info->alter_list.elements)
5367
  {
5368
    my_error(ER_BAD_FIELD_ERROR, MYF(0),
5369
             alter_info->alter_list.head()->name, table->s->table_name.str);
5370
    goto err;
5371
    }
5372
  if (!new_create_list.elements)
5373
    {
5374
    my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS),
5375
               MYF(0));
5376
    goto err;
5377
    }
5378
5379
    /*
5380
    Collect all keys which isn't in drop list. Add only those
5381
    for which some fields exists.
5382
    */
5383
5384
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
5385
    {
5386
    char *key_name= key_info->name;
5387
    Alter_drop *drop;
5388
    drop_it.rewind();
5389
    while ((drop=drop_it++))
5390
      {
5391
      if (drop->type == Alter_drop::KEY &&
5392
	  !my_strcasecmp(system_charset_info,key_name, drop->name))
5393
	break;
5394
      }
5395
    if (drop)
5396
        {
5397
      drop_it.remove();
5398
      continue;
5399
    }
5400
5401
    KEY_PART_INFO *key_part= key_info->key_part;
5402
    key_parts.empty();
5403
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
5404
    {
5405
      if (!key_part->field)
5406
	continue;				// Wrong field (from UNIREG)
5407
      const char *key_part_name=key_part->field->field_name;
5408
      Create_field *cfield;
5409
      field_it.rewind();
5410
      while ((cfield=field_it++))
5411
    {
5412
	if (cfield->change)
5413
    {
5414
	  if (!my_strcasecmp(system_charset_info, key_part_name,
5415
			     cfield->change))
5416
	    break;
5417
	}
5418
	else if (!my_strcasecmp(system_charset_info,
5419
				key_part_name, cfield->field_name))
5420
	  break;
5421
      }
5422
      if (!cfield)
5423
	continue;				// Field is removed
5424
      uint key_part_length=key_part->length;
5425
      if (cfield->field)			// Not new field
5426
      {
5427
        /*
5428
          If the field can't have only a part used in a key according to its
5429
          new type, or should not be used partially according to its
5430
          previous type, or the field length is less than the key part
5431
          length, unset the key part length.
5432
5433
          We also unset the key part length if it is the same as the
5434
          old field's length, so the whole new field will be used.
5435
5436
          BLOBs may have cfield->length == 0, which is why we test it before
5437
          checking whether cfield->length < key_part_length (in chars).
5438
         */
5439
        if (!Field::type_can_have_key_part(cfield->field->type()) ||
5440
            !Field::type_can_have_key_part(cfield->sql_type) ||
5441
            (cfield->field->field_length == key_part_length &&
5442
             !f_is_blob(key_part->key_type)) ||
5443
	    (cfield->length && (cfield->length < key_part_length /
5444
                                key_part->field->charset()->mbmaxlen)))
5445
	  key_part_length= 0;			// Use whole field
5446
      }
5447
      key_part_length /= key_part->field->charset()->mbmaxlen;
5448
      key_parts.push_back(new Key_part_spec(cfield->field_name,
5449
                                            strlen(cfield->field_name),
5450
					    key_part_length));
5451
    }
5452
    if (key_parts.elements)
5453
    {
5454
      KEY_CREATE_INFO key_create_info;
5455
      Key *key;
5456
      enum Key::Keytype key_type;
5457
      bzero((char*) &key_create_info, sizeof(key_create_info));
5458
5459
      key_create_info.algorithm= key_info->algorithm;
5460
      if (key_info->flags & HA_USES_BLOCK_SIZE)
5461
        key_create_info.block_size= key_info->block_size;
5462
      if (key_info->flags & HA_USES_COMMENT)
5463
        key_create_info.comment= key_info->comment;
5464
5465
      if (key_info->flags & HA_NOSAME)
5466
      {
5467
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
5468
          key_type= Key::PRIMARY;
5469
        else
5470
          key_type= Key::UNIQUE;
5471
      }
5472
      else
5473
        key_type= Key::MULTIPLE;
5474
5475
      key= new Key(key_type, key_name, strlen(key_name),
5476
                   &key_create_info,
5477
                   test(key_info->flags & HA_GENERATED_KEY),
5478
                   key_parts);
5479
      new_key_list.push_back(key);
5480
    }
5481
  }
5482
  {
5483
    Key *key;
5484
    while ((key=key_it++))			// Add new keys
5485
    {
5486
      if (key->type != Key::FOREIGN_KEY)
5487
        new_key_list.push_back(key);
5488
      if (key->name.str &&
5489
	  !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
5490
      {
5491
	my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
5492
        goto err;
5493
      }
5494
    }
5495
  }
5496
5497
  if (alter_info->drop_list.elements)
5498
  {
5499
    my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
5500
             alter_info->drop_list.head()->name);
5501
    goto err;
5502
  }
5503
  if (alter_info->alter_list.elements)
5504
  {
5505
    my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
5506
             alter_info->alter_list.head()->name);
5507
    goto err;
5508
  }
5509
5510
  if (!create_info->comment.str)
5511
  {
5512
    create_info->comment.str= table->s->comment.str;
5513
    create_info->comment.length= table->s->comment.length;
5514
  }
5515
5516
  table->file->update_create_info(create_info);
5517
  if ((create_info->table_options &
5518
       (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
5519
      (used_fields & HA_CREATE_USED_PACK_KEYS))
5520
    db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
5521
  if (create_info->table_options &
5522
      (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
5523
    db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM);
5524
  if (create_info->table_options &
5525
      (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE))
5526
    db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE |
5527
			  HA_OPTION_NO_DELAY_KEY_WRITE);
5528
  create_info->table_options|= db_create_options;
5529
5530
  if (table->s->tmp_table)
5531
    create_info->options|=HA_LEX_CREATE_TMP_TABLE;
5532
5533
  rc= FALSE;
5534
  alter_info->create_list.swap(new_create_list);
5535
  alter_info->key_list.swap(new_key_list);
5536
err:
5537
  DBUG_RETURN(rc);
5538
}
5539
5540
5541
/*
5542
  Alter table
5543
5544
  SYNOPSIS
5545
    mysql_alter_table()
5546
      thd              Thread handle
5547
      new_db           If there is a RENAME clause
5548
      new_name         If there is a RENAME clause
5549
      create_info      Information from the parsing phase about new
5550
                       table properties.
5551
      table_list       The table to change.
5552
      alter_info       Lists of fields, keys to be changed, added
5553
                       or dropped.
5554
      order_num        How many ORDER BY fields has been specified.
5555
      order            List of fields to ORDER BY.
5556
      ignore           Whether we have ALTER IGNORE TABLE
5557
5558
  DESCRIPTION
5559
    This is a veery long function and is everything but the kitchen sink :)
5560
    It is used to alter a table and not only by ALTER TABLE but also
5561
    CREATE|DROP INDEX are mapped on this function.
5562
5563
    When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
5564
    or both, then this function short cuts its operation by renaming
5565
    the table and/or enabling/disabling the keys. In this case, the FRM is
5566
    not changed, directly by mysql_alter_table. However, if there is a
5567
    RENAME + change of a field, or an index, the short cut is not used.
5568
    See how `create_list` is used to generate the new FRM regarding the
5569
    structure of the fields. The same is done for the indices of the table.
5570
5571
    Important is the fact, that this function tries to do as little work as
5572
    possible, by finding out whether a intermediate table is needed to copy
5573
    data into and when finishing the altering to use it as the original table.
5574
    For this reason the function compare_tables() is called, which decides
5575
    based on all kind of data how similar are the new and the original
5576
    tables.
5577
5578
  RETURN VALUES
5579
    FALSE  OK
5580
    TRUE   Error
5581
*/
5582
5583
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
5584
                       HA_CREATE_INFO *create_info,
5585
                       TABLE_LIST *table_list,
5586
                       Alter_info *alter_info,
5587
                       uint order_num, ORDER *order, bool ignore)
5588
{
5589
  TABLE *table, *new_table=0, *name_lock= 0;;
5590
  int error= 0;
5591
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
5592
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
5593
  char path[FN_REFLEN];
5594
  ha_rows copied= 0,deleted= 0;
5595
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
5596
  legacy_db_type table_type;
5597
  frm_type_enum frm_type;
5598
  DBUG_ENTER("mysql_alter_table");
5599
5600
  if (table_list && table_list->schema_table)
5601
  {
5602
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
5603
    DBUG_RETURN(TRUE);
5604
  }
5605
5606
  /*
5607
    Assign variables table_name, new_name, db, new_db, path
5608
    to simplify further comparisons: we want to see if it's a RENAME
5609
    later just by comparing the pointers, avoiding the need for strcmp.
5610
  */
5611
  thd_proc_info(thd, "init");
5612
  table_name=table_list->table_name;
5613
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
5614
  db=table_list->db;
5615
  if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
5616
    new_db= db;
5617
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
5618
5619
  mysql_ha_rm_tables(thd, table_list, FALSE);
5620
5621
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
5622
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
5623
    /* Conditionally writes to binlog. */
5624
    DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
5625
						   alter_info->tablespace_op));
5626
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
5627
           "/", table_name, reg_ext, NullS);
5628
  (void) unpack_filename(new_name_buff, new_name_buff);
5629
  /*
5630
    If this is just a rename of a view, short cut to the
5631
    following scenario: 1) lock LOCK_open 2) do a RENAME
5632
    2) unlock LOCK_open.
5633
    This is a copy-paste added to make sure
5634
    ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
5635
    as an independent branch in mysql_execute_command. The need
5636
    for a copy-paste arose because the main code flow of ALTER TABLE
5637
    ... RENAME tries to use open_ltable, which does not work for views
5638
    (open_ltable was never modified to merge table lists of child tables
5639
    into the main table list, like open_tables does).
5640
    This code is wrong and will be removed, please do not copy.
5641
  */
5642
  frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
5643
5644
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
5645
    DBUG_RETURN(TRUE);
5646
  table->use_all_columns();
5647
5648
  /*
5649
    Prohibit changing of the UNION list of a non-temporary MERGE table
5650
    under LOCK tables. It would be quite difficult to reuse a shrinked
5651
    set of tables from the old table or to open a new TABLE object for
5652
    an extended list and verify that they belong to locked tables.
5653
  */
5654
  if (thd->locked_tables &&
5655
      (create_info->used_fields & HA_CREATE_USED_UNION) &&
5656
      (table->s->tmp_table == NO_TMP_TABLE))
5657
  {
5658
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
5659
    DBUG_RETURN(TRUE);
5660
  }
5661
5662
  /* Check that we are not trying to rename to an existing table */
5663
  if (new_name)
5664
  {
5665
    DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
5666
    strmov(new_name_buff,new_name);
5667
    strmov(new_alias= new_alias_buff, new_name);
5668
    if (lower_case_table_names)
5669
    {
5670
      if (lower_case_table_names != 2)
5671
      {
5672
	my_casedn_str(files_charset_info, new_name_buff);
5673
	new_alias= new_name;			// Create lower case table name
5674
      }
5675
      my_casedn_str(files_charset_info, new_name);
5676
    }
5677
    if (new_db == db &&
5678
	!my_strcasecmp(table_alias_charset, new_name_buff, table_name))
5679
    {
5680
      /*
5681
	Source and destination table names are equal: make later check
5682
	easier.
5683
      */
5684
      new_alias= new_name= table_name;
5685
    }
5686
    else
5687
    {
5688
      if (table->s->tmp_table != NO_TMP_TABLE)
5689
      {
5690
	if (find_temporary_table(thd,new_db,new_name_buff))
5691
	{
5692
	  my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
5693
	  DBUG_RETURN(TRUE);
5694
	}
5695
      }
5696
      else
5697
      {
5698
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
5699
          DBUG_RETURN(TRUE);
5700
        if (!name_lock)
5701
        {
5702
	  my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
5703
	  DBUG_RETURN(TRUE);
5704
        }
5705
5706
        build_table_filename(new_name_buff, sizeof(new_name_buff),
5707
                             new_db, new_name_buff, reg_ext, 0);
5708
        if (!access(new_name_buff, F_OK))
5709
	{
5710
	  /* Table will be closed in do_command() */
5711
	  my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
5712
	  goto err;
5713
	}
5714
      }
5715
    }
5716
  }
5717
  else
5718
  {
5719
    new_alias= (lower_case_table_names == 2) ? alias : table_name;
5720
    new_name= table_name;
5721
  }
5722
5723
  old_db_type= table->s->db_type();
5724
  if (!create_info->db_type)
5725
  {
5726
    create_info->db_type= old_db_type;
5727
  }
5728
5729
  if (check_engine(thd, new_name, create_info))
5730
    goto err;
5731
  new_db_type= create_info->db_type;
5732
5733
  if (new_db_type != old_db_type ||
5734
      !table->file->can_switch_engines())
5735
  {
5736
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
5737
    goto err;
5738
  }
5739
5740
  if (create_info->row_type == ROW_TYPE_NOT_USED)
5741
    create_info->row_type= table->s->row_type;
5742
5743
  DBUG_PRINT("info", ("old type: %s  new type: %s",
5744
             ha_resolve_storage_engine_name(old_db_type),
5745
             ha_resolve_storage_engine_name(new_db_type)));
5746
  if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
5747
      ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
5748
  {
5749
    DBUG_PRINT("info", ("doesn't support alter"));
5750
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
5751
    goto err;
5752
  }
5753
5754
  thd_proc_info(thd, "setup");
5755
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
5756
      !table->s->tmp_table) // no need to touch frm
5757
  {
5758
    switch (alter_info->keys_onoff) {
5759
    case LEAVE_AS_IS:
5760
      break;
5761
    case ENABLE:
5762
      /*
5763
        wait_while_table_is_used() ensures that table being altered is
5764
        opened only by this thread and that TABLE::TABLE_SHARE::version
5765
        of TABLE object corresponding to this table is 0.
5766
        The latter guarantees that no DML statement will open this table
5767
        until ALTER TABLE finishes (i.e. until close_thread_tables())
5768
        while the fact that the table is still open gives us protection
5769
        from concurrent DDL statements.
5770
      */
5771
      VOID(pthread_mutex_lock(&LOCK_open));
5772
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5773
      VOID(pthread_mutex_unlock(&LOCK_open));
5774
      DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
5775
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
5776
      /* COND_refresh will be signaled in close_thread_tables() */
5777
      break;
5778
    case DISABLE:
5779
      VOID(pthread_mutex_lock(&LOCK_open));
5780
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5781
      VOID(pthread_mutex_unlock(&LOCK_open));
5782
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
5783
      /* COND_refresh will be signaled in close_thread_tables() */
5784
      break;
5785
    default:
5786
      DBUG_ASSERT(FALSE);
5787
      error= 0;
5788
      break;
5789
    }
5790
    if (error == HA_ERR_WRONG_COMMAND)
5791
    {
5792
      error= 0;
5793
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
5794
			  ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
5795
			  table->alias);
5796
    }
5797
5798
    VOID(pthread_mutex_lock(&LOCK_open));
5799
    /*
5800
      Unlike to the above case close_cached_table() below will remove ALL
5801
      instances of TABLE from table cache (it will also remove table lock
5802
      held by this thread). So to make actual table renaming and writing
5803
      to binlog atomic we have to put them into the same critical section
5804
      protected by LOCK_open mutex. This also removes gap for races between
5805
      access() and mysql_rename_table() calls.
5806
    */
5807
5808
    if (!error && (new_name != table_name || new_db != db))
5809
    {
5810
      thd_proc_info(thd, "rename");
5811
      /*
5812
        Then do a 'simple' rename of the table. First we need to close all
5813
        instances of 'source' table.
5814
      */
5815
      close_cached_table(thd, table);
5816
      /*
5817
        Then, we want check once again that target table does not exist.
5818
        Actually the order of these two steps does not matter since
5819
        earlier we took name-lock on the target table, so we do them
5820
        in this particular order only to be consistent with 5.0, in which
5821
        we don't take this name-lock and where this order really matters.
5822
        TODO: Investigate if we need this access() check at all.
5823
      */
5824
      if (!access(new_name_buff,F_OK))
5825
      {
5826
	my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
5827
	error= -1;
5828
      }
5829
      else
5830
      {
5831
	*fn_ext(new_name)=0;
5832
	if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias, 0))
5833
	  error= -1;
5834
        else if (0)
5835
      {
5836
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
5837
                                  table_name, 0));
5838
          error= -1;
5839
      }
5840
    }
5841
  }
5842
5843
    if (error == HA_ERR_WRONG_COMMAND)
5844
  {
5845
      error= 0;
5846
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
5847
			  ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
5848
			  table->alias);
5849
  }
5850
5851
    if (!error)
5852
    {
5853
      write_bin_log(thd, TRUE, thd->query, thd->query_length);
5854
      my_ok(thd);
5855
  }
5856
    else if (error > 0)
5857
  {
5858
      table->file->print_error(error, MYF(0));
5859
      error= -1;
5860
    }
5861
    if (name_lock)
5862
      unlink_open_table(thd, name_lock, FALSE);
5863
    VOID(pthread_mutex_unlock(&LOCK_open));
5864
    table_list->table= NULL;                    // For query cache
5865
    DBUG_RETURN(error);
5866
  }
5867
5868
  /* We have to do full alter table. */
5869
5870
    /*
5871
    If the old table had partitions and we are doing ALTER TABLE ...
5872
    engine= <new_engine>, the new table must preserve the original
5873
    partitioning. That means that the new engine is still the
5874
    partitioning engine, not the engine specified in the parser.
5875
    This is discovered  in prep_alter_part_table, which in such case
5876
    updates create_info->db_type.
5877
    Now we need to update the stack copy of create_info->db_type,
5878
    as otherwise we won't be able to correctly move the files of the
5879
    temporary table to the result table files.
5880
  */
5881
  new_db_type= create_info->db_type;
5882
5883
  if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
5884
      goto err;
5885
5886
  set_table_default_charset(thd, create_info, db);
5887
5888
5889
  if (thd->variables.old_alter_table
5890
      || (table->s->db_type() != create_info->db_type)
5891
     )
5892
  {
5893
    if (alter_info->build_method == HA_BUILD_ONLINE)
5894
    {
5895
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
5896
      goto err;
5897
    }
5898
    alter_info->build_method= HA_BUILD_OFFLINE;
5899
  }
5900
5901
  if (alter_info->build_method != HA_BUILD_OFFLINE)
5902
  {
5903
    TABLE *altered_table= 0;
5904
    HA_ALTER_INFO ha_alter_info;
5905
    HA_ALTER_FLAGS ha_alter_flags;
5906
    uint table_changes= IS_EQUAL_YES;
5907
    bool need_copy_table= TRUE;
5908
    /* Check how much the tables differ. */
5909
    if (compare_tables(thd, table, alter_info,
5910
                       create_info, order_num,
5911
                       &ha_alter_flags,
5912
                       &ha_alter_info,
5913
                       &table_changes))
5914
    {
5915
      DBUG_RETURN(TRUE);
5916
    }
5917
5918
    /*
5919
      Check if storage engine supports altering the table
5920
      on-line.
5921
    */
5922
5923
#ifndef DBUG_OFF
5924
    {
5925
      char dbug_string[HA_MAX_ALTER_FLAGS+1];
5926
      ha_alter_flags.print(dbug_string);
5927
      DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
5928
                          need_copy_table, table_changes,
5929
                          (char *) dbug_string));
5930
    }
5931
#endif
5932
5933
    /*
5934
      If table is not renamed, changed database and
5935
      some change was detected then check if engine
5936
      can do the change on-line
5937
    */
5938
    if (new_name == table_name && new_db == db &&
5939
        ha_alter_flags.is_set())
5940
    {
5941
      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
5942
5943
      /*
5944
        If no table rename,
5945
        check if table can be altered on-line
5946
      */
5947
      if (!(altered_table= create_altered_table(thd,
5948
                                                table,
5949
                                                new_db,
5950
                                                create_info,
5951
                                                &tmp_alter_info,
5952
                                                !strcmp(db, new_db))))
5953
        goto err;
5954
5955
      switch (table->file->check_if_supported_alter(altered_table,
5956
                                                    create_info,
5957
                                                    &ha_alter_flags,
5958
                                                    table_changes)) {
5959
      case HA_ALTER_SUPPORTED_WAIT_LOCK:
5960
      case HA_ALTER_SUPPORTED_NO_LOCK:
5961
        /*
5962
          @todo: Currently we always acquire an exclusive name
5963
          lock on the table metadata when performing fast or online
5964
          ALTER TABLE. In future we may consider this unnecessary,
5965
          and narrow the scope of the exclusive name lock to only
5966
          cover manipulation with .frms. Storage engine API
5967
          call check_if_supported_alter has provision for this
5968
          already now.
5969
        */
5970
        need_copy_table= FALSE;
5971
        break;
5972
      case HA_ALTER_NOT_SUPPORTED:
5973
        if (alter_info->build_method == HA_BUILD_ONLINE)
5974
        {
5975
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
5976
          close_temporary_table(thd, altered_table, 1, 1);
5977
          goto err;
5978
        }
5979
        need_copy_table= TRUE;
5980
        break;
5981
      case HA_ALTER_ERROR:
5982
      default:
5983
        close_temporary_table(thd, altered_table, 1, 1);
5984
        goto err;
5985
      }
5986
#ifndef DBUG_OFF
5987
      {
5988
        char dbug_string[HA_MAX_ALTER_FLAGS+1];
5989
        ha_alter_flags.print(dbug_string);
5990
        DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
5991
                            need_copy_table, table_changes,
5992
                            (char *) dbug_string));
5993
      }
5994
#endif
5995
5996
    }
5997
    /* TODO need to check if changes can be handled as fast ALTER TABLE */
5998
    if (!altered_table)
5999
      need_copy_table= TRUE;
6000
6001
    if (!need_copy_table)
6002
    {
6003
      error= mysql_fast_or_online_alter_table(thd,
6004
                                              table,
6005
                                              altered_table,
6006
                                              create_info,
6007
                                              &ha_alter_info,
6008
                                              &ha_alter_flags,
6009
                                              alter_info->keys_onoff);
6010
      if (thd->lock)
6011
      {
6012
        mysql_unlock_tables(thd, thd->lock);
6013
        thd->lock=0;
6014
      }
6015
      close_temporary_table(thd, altered_table, 1, 1);
6016
6017
      if (error)
6018
      {
6019
        switch (error) {
6020
        case(-1):
6021
          goto err_with_placeholders;
6022
        default:
6023
          goto err;
6024
        }
6025
      }
6026
      else
6027
      {
6028
        pthread_mutex_lock(&LOCK_open);
6029
        goto end_online;
6030
      }
6031
    }
6032
6033
    if (altered_table)
6034
      close_temporary_table(thd, altered_table, 1, 1);
6035
  }
6036
6037
  my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
6038
              current_pid, thd->thread_id);
6039
  /* Safety fix for innodb */
6040
  if (lower_case_table_names)
6041
    my_casedn_str(files_charset_info, tmp_name);
6042
6043
6044
  /* Create a temporary table with the new format */
6045
  if ((error= create_temporary_table(thd, table, new_db, tmp_name, 
6046
                                     create_info, alter_info, 
6047
                                     !strcmp(db, new_db))))
6048
  {
6049
    goto err;
6050
  }
6051
6052
  /* Open the table so we need to copy the data to it. */
6053
  if (table->s->tmp_table)
6054
  {
6055
    TABLE_LIST tbl;
6056
    bzero((void*) &tbl, sizeof(tbl));
6057
    tbl.db= new_db;
6058
    tbl.table_name= tbl.alias= tmp_name;
6059
    /* Table is in thd->temporary_tables */
6060
    new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
6061
                          MYSQL_LOCK_IGNORE_FLUSH);
6062
  }
6063
  else
6064
  {
6065
    char path[FN_REFLEN];
6066
    /* table is a normal table: Create temporary table in same directory */
6067
    build_table_filename(path, sizeof(path), new_db, tmp_name, "",
6068
                         FN_IS_TMP);
6069
    /* Open our intermediate table */
6070
    new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
6071
  }
6072
  if (!new_table)
6073
    goto err1;
6074
6075
  /* Copy the data if necessary. */
6076
  thd->count_cuted_fields= CHECK_FIELD_WARN;	// calc cuted fields
6077
  thd->cuted_fields=0L;
6078
  thd_proc_info(thd, "copy to tmp table");
6079
  copied=deleted=0;
6080
  /*
6081
    We do not copy data for MERGE tables. Only the children have data.
6082
    MERGE tables have HA_NO_COPY_ON_ALTER set.
6083
  */
6084
  if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
6085
  {
6086
    /* We don't want update TIMESTAMP fields during ALTER TABLE. */
6087
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
6088
    new_table->next_number_field=new_table->found_next_number_field;
6089
    error= copy_data_between_tables(table, new_table,
6090
                                    alter_info->create_list, ignore,
6091
                                   order_num, order, &copied, &deleted,
6092
                                    alter_info->keys_onoff,
6093
                                    alter_info->error_if_not_empty);
6094
  }
6095
  else
6096
  {
6097
    VOID(pthread_mutex_lock(&LOCK_open));
6098
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
6099
    VOID(pthread_mutex_unlock(&LOCK_open));
6100
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
6101
                            alter_info->keys_onoff);
6102
    error= ha_autocommit_or_rollback(thd, 0);
6103
    if (end_active_trans(thd))
6104
      error= 1;
6105
  }
6106
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
6107
6108
  if (table->s->tmp_table != NO_TMP_TABLE)
6109
  {
6110
    /* We changed a temporary table */
6111
    if (error)
6112
      goto err1;
6113
    /* Close lock if this is a transactional table */
6114
    if (thd->lock)
6115
    {
6116
      mysql_unlock_tables(thd, thd->lock);
6117
      thd->lock=0;
6118
    }
6119
    /* Remove link to old table and rename the new one */
6120
    close_temporary_table(thd, table, 1, 1);
6121
    /* Should pass the 'new_name' as we store table name in the cache */
6122
    if (rename_temporary_table(thd, new_table, new_db, new_name))
6123
      goto err1;
6124
    /* We don't replicate alter table statement on temporary tables */
6125
    if (!thd->current_stmt_binlog_row_based)
6126
      write_bin_log(thd, TRUE, thd->query, thd->query_length);
6127
    goto end_temporary;
6128
  }
6129
6130
  if (new_table)
6131
  {
6132
    /*
6133
      Close the intermediate table that will be the new table.
6134
      Note that MERGE tables do not have their children attached here.
6135
    */
6136
    intern_close_table(new_table);
6137
    my_free(new_table,MYF(0));
6138
  }
6139
  VOID(pthread_mutex_lock(&LOCK_open));
6140
  if (error)
6141
  {
6142
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
6143
    VOID(pthread_mutex_unlock(&LOCK_open));
6144
    goto err;
6145
  }
6146
6147
  /*
6148
    Data is copied. Now we:
6149
    1) Wait until all other threads close old version of table.
6150
    2) Close instances of table open by this thread and replace them
6151
       with exclusive name-locks.
6152
    3) Rename the old table to a temp name, rename the new one to the
6153
       old name.
6154
    4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
6155
       we reopen new version of table.
6156
    5) Write statement to the binary log.
6157
    6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
6158
       remove name-locks from list of open tables and table cache.
6159
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
6160
       call to remove name-locks from table cache and list of open table.
6161
  */
6162
6163
  thd_proc_info(thd, "rename result table");
6164
  my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
6165
	      current_pid, thd->thread_id);
6166
  if (lower_case_table_names)
6167
    my_casedn_str(files_charset_info, old_name);
6168
6169
  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
6170
  close_data_files_and_morph_locks(thd, db, table_name);
6171
6172
  error=0;
6173
  save_old_db_type= old_db_type;
6174
6175
  /*
6176
    This leads to the storage engine (SE) not being notified for renames in
6177
    mysql_rename_table(), because we just juggle with the FRM and nothing
6178
    more. If we have an intermediate table, then we notify the SE that
6179
    it should become the actual table. Later, we will recycle the old table.
6180
    However, in case of ALTER TABLE RENAME there might be no intermediate
6181
    table. This is when the old and new tables are compatible, according to
6182
    compare_table(). Then, we need one additional call to
6183
    mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
6184
    actual rename in the SE and the FRM is not touched. Note that, if the
6185
    table is renamed and the SE is also changed, then an intermediate table
6186
    is created and the additional call will not take place.
6187
  */
6188
  if (mysql_rename_table(old_db_type, db, table_name, db, old_name,
6189
                         FN_TO_IS_TMP))
6190
  {
6191
    error=1;
6192
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
6193
  }
6194
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
6195
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
6196
  {
6197
    /* Try to get everything back. */
6198
    error=1;
6199
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
6200
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
6201
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
6202
                            FN_FROM_IS_TMP));
6203
  }
6204
6205
  if (error)
6206
  {
6207
    /* This shouldn't happen. But let us play it safe. */
6208
    goto err_with_placeholders;
6209
  }
6210
6211
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
6212
6213
end_online:
6214
  if (thd->locked_tables && new_name == table_name && new_db == db)
6215
  {
6216
    thd->in_lock_tables= 1;
6217
    error= reopen_tables(thd, 1, 1);
6218
    thd->in_lock_tables= 0;
6219
    if (error)
6220
      goto err_with_placeholders;
6221
  }
6222
  VOID(pthread_mutex_unlock(&LOCK_open));
6223
6224
  thd_proc_info(thd, "end");
6225
6226
  DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
6227
6228
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
6229
                      thd->query, thd->query_length,
6230
                      db, table_name);
6231
6232
  DBUG_ASSERT(!(mysql_bin_log.is_open() &&
6233
                thd->current_stmt_binlog_row_based &&
6234
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
6235
  write_bin_log(thd, TRUE, thd->query, thd->query_length);
6236
6237
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
6238
  {
6239
    /*
6240
      For the alter table to be properly flushed to the logs, we
6241
      have to open the new table.  If not, we get a problem on server
6242
      shutdown. But we do not need to attach MERGE children.
6243
    */
6244
    char path[FN_REFLEN];
6245
    TABLE *t_table;
6246
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
6247
    t_table= open_temporary_table(thd, path, new_db, tmp_name, FALSE, OTM_OPEN);
6248
    if (t_table)
6249
    {
6250
      intern_close_table(t_table);
6251
      my_free(t_table, MYF(0));
6252
    }
6253
    else
6254
      sql_print_warning("Could not open table %s.%s after rename\n",
6255
                        new_db,table_name);
6256
    ha_flush_logs(old_db_type);
6257
  }
6258
  table_list->table=0;				// For query cache
6259
6260
  if (thd->locked_tables && (new_name != table_name || new_db != db))
6261
  {
6262
    /*
6263
      If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
6264
      to remove placeholders for the old table and for the target table
6265
      from the list of open tables and table cache. If we are not under
6266
      LOCK TABLES we can rely on close_thread_tables() doing this job.
6267
    */
6268
    pthread_mutex_lock(&LOCK_open);
6269
    unlink_open_table(thd, table, FALSE);
6270
    unlink_open_table(thd, name_lock, FALSE);
6271
    pthread_mutex_unlock(&LOCK_open);
6272
  }
6273
6274
end_temporary:
6275
  my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
6276
	      (ulong) (copied + deleted), (ulong) deleted,
6277
	      (ulong) thd->cuted_fields);
6278
  my_ok(thd, copied + deleted, 0L, tmp_name);
6279
  thd->some_tables_deleted=0;
6280
  DBUG_RETURN(FALSE);
6281
6282
err1:
6283
  if (new_table)
6284
  {
6285
    /* close_temporary_table() frees the new_table pointer. */
6286
    close_temporary_table(thd, new_table, 1, 1);
6287
  }
6288
  else
6289
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
6290
6291
err:
6292
  /*
6293
    No default value was provided for a DATE/DATETIME field, the
6294
    current sql_mode doesn't allow the '0000-00-00' value and
6295
    the table to be altered isn't empty.
6296
    Report error here.
6297
  */
6298
  if (alter_info->error_if_not_empty && thd->row_count)
6299
  {
6300
    const char *f_val= 0;
6301
    enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
6302
    switch (alter_info->datetime_field->sql_type)
6303
    {
6304
      case MYSQL_TYPE_DATE:
6305
      case MYSQL_TYPE_NEWDATE:
6306
        f_val= "0000-00-00";
6307
        t_type= MYSQL_TIMESTAMP_DATE;
6308
        break;
6309
      case MYSQL_TYPE_DATETIME:
6310
        f_val= "0000-00-00 00:00:00";
6311
        t_type= MYSQL_TIMESTAMP_DATETIME;
6312
        break;
6313
      default:
6314
        /* Shouldn't get here. */
6315
        DBUG_ASSERT(0);
6316
    }
6317
    bool save_abort_on_warning= thd->abort_on_warning;
6318
    thd->abort_on_warning= TRUE;
6319
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
6320
                                 f_val, strlength(f_val), t_type,
6321
                                 alter_info->datetime_field->field_name);
6322
    thd->abort_on_warning= save_abort_on_warning;
6323
  }
6324
  if (name_lock)
6325
  {
6326
    pthread_mutex_lock(&LOCK_open);
6327
    unlink_open_table(thd, name_lock, FALSE);
6328
    pthread_mutex_unlock(&LOCK_open);
6329
  }
6330
  DBUG_RETURN(TRUE);
6331
6332
err_with_placeholders:
6333
  /*
6334
    An error happened while we were holding exclusive name-lock on table
6335
    being altered. To be safe under LOCK TABLES we should remove placeholders
6336
    from list of open tables list and table cache.
6337
  */
6338
  unlink_open_table(thd, table, FALSE);
6339
  if (name_lock)
6340
    unlink_open_table(thd, name_lock, FALSE);
6341
  VOID(pthread_mutex_unlock(&LOCK_open));
6342
  DBUG_RETURN(TRUE);
6343
}
6344
/* mysql_alter_table */
6345
6346
static int
6347
copy_data_between_tables(TABLE *from,TABLE *to,
6348
			 List<Create_field> &create,
6349
                         bool ignore,
6350
			 uint order_num, ORDER *order,
6351
			 ha_rows *copied,
6352
			 ha_rows *deleted,
6353
                         enum enum_enable_or_disable keys_onoff,
6354
                         bool error_if_not_empty)
6355
{
6356
  int error;
6357
  Copy_field *copy,*copy_end;
6358
  ulong found_count,delete_count;
6359
  THD *thd= current_thd;
6360
  uint length= 0;
6361
  SORT_FIELD *sortorder;
6362
  READ_RECORD info;
6363
  TABLE_LIST   tables;
6364
  List<Item>   fields;
6365
  List<Item>   all_fields;
6366
  ha_rows examined_rows;
6367
  bool auto_increment_field_copied= 0;
6368
  ulong save_sql_mode;
6369
  ulonglong prev_insert_id;
6370
  DBUG_ENTER("copy_data_between_tables");
6371
6372
  /*
6373
    Turn off recovery logging since rollback of an alter table is to
6374
    delete the new table so there is no need to log the changes to it.
6375
    
6376
    This needs to be done before external_lock
6377
  */
6378
  error= ha_enable_transaction(thd, FALSE);
6379
  if (error)
6380
    DBUG_RETURN(-1);
6381
  
6382
  if (!(copy= new Copy_field[to->s->fields]))
6383
    DBUG_RETURN(-1);				/* purecov: inspected */
6384
6385
  if (to->file->ha_external_lock(thd, F_WRLCK))
6386
    DBUG_RETURN(-1);
6387
6388
  /* We need external lock before we can disable/enable keys */
6389
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
6390
6391
  /* We can abort alter table for any table type */
6392
  thd->abort_on_warning= !ignore;
6393
6394
  from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
6395
  to->file->ha_start_bulk_insert(from->file->stats.records);
6396
6397
  save_sql_mode= thd->variables.sql_mode;
6398
6399
  List_iterator<Create_field> it(create);
6400
  Create_field *def;
6401
  copy_end=copy;
6402
  for (Field **ptr=to->field ; *ptr ; ptr++)
6403
  {
6404
    def=it++;
6405
    if (def->field)
6406
    {
6407
      if (*ptr == to->next_number_field)
6408
      {
6409
        auto_increment_field_copied= TRUE;
6410
        /*
6411
          If we are going to copy contents of one auto_increment column to
6412
          another auto_increment column it is sensible to preserve zeroes.
6413
          This condition also covers case when we are don't actually alter
6414
          auto_increment column.
6415
        */
6416
        if (def->field == from->found_next_number_field)
6417
          thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
6418
      }
6419
      (copy_end++)->set(*ptr,def->field,0);
6420
    }
6421
6422
  }
6423
6424
  found_count=delete_count=0;
6425
6426
  if (order)
6427
  {
6428
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
6429
    {
6430
      char warn_buff[MYSQL_ERRMSG_SIZE];
6431
      my_snprintf(warn_buff, sizeof(warn_buff), 
6432
                  "ORDER BY ignored as there is a user-defined clustered index"
6433
                  " in the table '%-.192s'", from->s->table_name.str);
6434
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
6435
                   warn_buff);
6436
    }
6437
    else
6438
    {
6439
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
6440
                                                MYF(MY_FAE | MY_ZEROFILL));
6441
      bzero((char *) &tables, sizeof(tables));
6442
      tables.table= from;
6443
      tables.alias= tables.table_name= from->s->table_name.str;
6444
      tables.db= from->s->db.str;
6445
      error= 1;
6446
6447
      if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
6448
          setup_order(thd, thd->lex->select_lex.ref_pointer_array,
6449
                      &tables, fields, all_fields, order) ||
6450
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
6451
          (from->sort.found_records= filesort(thd, from, sortorder, length,
6452
                                              (SQL_SELECT *) 0, HA_POS_ERROR,
6453
                                              1, &examined_rows)) ==
6454
          HA_POS_ERROR)
6455
        goto err;
6456
    }
6457
  };
6458
6459
  /* Tell handler that we have values for all columns in the to table */
6460
  to->use_all_columns();
6461
  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
6462
  if (ignore)
6463
    to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
6464
  thd->row_count= 0;
6465
  restore_record(to, s->default_values);        // Create empty record
6466
  while (!(error=info.read_record(&info)))
6467
  {
6468
    if (thd->killed)
6469
    {
6470
      thd->send_kill_message();
6471
      error= 1;
6472
      break;
6473
    }
6474
    thd->row_count++;
6475
    /* Return error if source table isn't empty. */
6476
    if (error_if_not_empty)
6477
    {
6478
      error= 1;
6479
      break;
6480
    }
6481
    if (to->next_number_field)
6482
    {
6483
      if (auto_increment_field_copied)
6484
        to->auto_increment_field_not_null= TRUE;
6485
      else
6486
        to->next_number_field->reset();
6487
    }
6488
    
6489
    for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
6490
    {
6491
      copy_ptr->do_copy(copy_ptr);
6492
    }
6493
    prev_insert_id= to->file->next_insert_id;
6494
    error=to->file->ha_write_row(to->record[0]);
6495
    to->auto_increment_field_not_null= FALSE;
6496
    if (error)
6497
    {
6498
      if (!ignore ||
6499
          to->file->is_fatal_error(error, HA_CHECK_DUP))
6500
      {
6501
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
6502
         {
6503
           uint key_nr= to->file->get_dup_key(error);
6504
           if ((int) key_nr >= 0)
6505
           {
6506
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
6507
             if (key_nr == 0 &&
6508
                 (to->key_info[0].key_part[0].field->flags &
6509
                  AUTO_INCREMENT_FLAG))
6510
               err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
6511
             to->file->print_keydup_error(key_nr, err_msg);
6512
             break;
6513
           }
6514
         }
6515
6516
	to->file->print_error(error,MYF(0));
6517
	break;
6518
      }
6519
      to->file->restore_auto_increment(prev_insert_id);
6520
      delete_count++;
6521
    }
6522
    else
6523
      found_count++;
6524
  }
6525
  end_read_record(&info);
6526
  free_io_cache(from);
6527
  delete [] copy;				// This is never 0
6528
6529
  if (to->file->ha_end_bulk_insert() && error <= 0)
6530
  {
6531
    to->file->print_error(my_errno,MYF(0));
6532
    error=1;
6533
  }
6534
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
6535
6536
  if (ha_enable_transaction(thd, TRUE))
6537
  {
6538
    error= 1;
6539
    goto err;
6540
  }
6541
6542
  /*
6543
    Ensure that the new table is saved properly to disk so that we
6544
    can do a rename
6545
  */
6546
  if (ha_autocommit_or_rollback(thd, 0))
6547
    error=1;
6548
  if (end_active_trans(thd))
6549
    error=1;
6550
6551
 err:
6552
  thd->variables.sql_mode= save_sql_mode;
6553
  thd->abort_on_warning= 0;
6554
  free_io_cache(from);
6555
  *copied= found_count;
6556
  *deleted=delete_count;
6557
  to->file->ha_release_auto_increment();
6558
  if (to->file->ha_external_lock(thd,F_UNLCK))
6559
    error=1;
6560
  DBUG_RETURN(error > 0 ? -1 : 0);
6561
}
6562
6563
6564
/*
6565
  Recreates tables by calling mysql_alter_table().
6566
6567
  SYNOPSIS
6568
    mysql_recreate_table()
6569
    thd			Thread handler
6570
    tables		Tables to recreate
6571
6572
 RETURN
6573
    Like mysql_alter_table().
6574
*/
6575
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
6576
{
6577
  HA_CREATE_INFO create_info;
6578
  Alter_info alter_info;
6579
6580
  DBUG_ENTER("mysql_recreate_table");
6581
  DBUG_ASSERT(!table_list->next_global);
6582
  /*
6583
    table_list->table has been closed and freed. Do not reference
6584
    uninitialized data. open_tables() could fail.
6585
  */
6586
  table_list->table= NULL;
6587
6588
  bzero((char*) &create_info, sizeof(create_info));
6589
  create_info.row_type=ROW_TYPE_NOT_USED;
6590
  create_info.default_table_charset=default_charset_info;
6591
  /* Force alter table to recreate table */
6592
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
6593
  DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
6594
                                table_list, &alter_info, 0,
6595
                                (ORDER *) 0, 0));
6596
}
6597
6598
6599
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
6600
                          HA_CHECK_OPT *check_opt)
6601
{
6602
  TABLE_LIST *table;
6603
  List<Item> field_list;
6604
  Item *item;
6605
  Protocol *protocol= thd->protocol;
6606
  DBUG_ENTER("mysql_checksum_table");
6607
6608
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
6609
  item->maybe_null= 1;
6610
  field_list.push_back(item= new Item_int("Checksum", (longlong) 1,
6611
                                          MY_INT64_NUM_DECIMAL_DIGITS));
6612
  item->maybe_null= 1;
6613
  if (protocol->send_fields(&field_list,
6614
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
6615
    DBUG_RETURN(TRUE);
6616
6617
  /* Open one table after the other to keep lock time as short as possible. */
6618
  for (table= tables; table; table= table->next_local)
6619
  {
6620
    char table_name[NAME_LEN*2+2];
6621
    TABLE *t;
6622
6623
    strxmov(table_name, table->db ,".", table->table_name, NullS);
6624
6625
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
6626
    thd->clear_error();			// these errors shouldn't get client
6627
6628
    protocol->prepare_for_resend();
6629
    protocol->store(table_name, system_charset_info);
6630
6631
    if (!t)
6632
    {
6633
      /* Table didn't exist */
6634
      protocol->store_null();
6635
      thd->clear_error();
6636
    }
6637
    else
6638
    {
6639
      if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
6640
	  !(check_opt->flags & T_EXTEND))
6641
	protocol->store((ulonglong)t->file->checksum());
6642
      else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
6643
	       (check_opt->flags & T_QUICK))
6644
	protocol->store_null();
6645
      else
6646
      {
6647
	/* calculating table's checksum */
6648
	ha_checksum crc= 0;
6649
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
6650
6651
        t->use_all_columns();
6652
6653
	if (t->file->ha_rnd_init(1))
6654
	  protocol->store_null();
6655
	else
6656
	{
6657
	  for (;;)
6658
	  {
6659
	    ha_checksum row_crc= 0;
6660
            int error= t->file->rnd_next(t->record[0]);
6661
            if (unlikely(error))
6662
            {
6663
              if (error == HA_ERR_RECORD_DELETED)
6664
                continue;
6665
              break;
6666
            }
6667
	    if (t->s->null_bytes)
6668
            {
6669
              /* fix undefined null bits */
6670
              t->record[0][t->s->null_bytes-1] |= null_mask;
6671
              if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
6672
                t->record[0][0] |= 1;
6673
6674
	      row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
6675
            }
6676
6677
	    for (uint i= 0; i < t->s->fields; i++ )
6678
	    {
6679
	      Field *f= t->field[i];
6680
	      if ((f->type() == MYSQL_TYPE_BLOB) ||
6681
                  (f->type() == MYSQL_TYPE_VARCHAR))
6682
	      {
6683
		String tmp;
6684
		f->val_str(&tmp);
6685
		row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
6686
	      }
6687
	      else
6688
		row_crc= my_checksum(row_crc, f->ptr,
6689
				     f->pack_length());
6690
	    }
6691
6692
	    crc+= row_crc;
6693
	  }
6694
	  protocol->store((ulonglong)crc);
6695
          t->file->ha_rnd_end();
6696
	}
6697
      }
6698
      thd->clear_error();
6699
      close_thread_tables(thd);
6700
      table->table=0;				// For query cache
6701
    }
6702
    if (protocol->write())
6703
      goto err;
6704
  }
6705
6706
  my_eof(thd);
6707
  DBUG_RETURN(FALSE);
6708
6709
 err:
6710
  close_thread_tables(thd);			// Shouldn't be needed
6711
  if (table)
6712
    table->table=0;
6713
  DBUG_RETURN(TRUE);
6714
}
6715
6716
static bool check_engine(THD *thd, const char *table_name,
6717
                         HA_CREATE_INFO *create_info)
6718
{
6719
  handlerton **new_engine= &create_info->db_type;
6720
  handlerton *req_engine= *new_engine;
6721
  bool no_substitution= 1;
6722
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
6723
                                  no_substitution, 1)))
6724
    return TRUE;
6725
6726
  if (req_engine && req_engine != *new_engine)
6727
  {
6728
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
6729
                       ER_WARN_USING_OTHER_HANDLER,
6730
                       ER(ER_WARN_USING_OTHER_HANDLER),
6731
                       ha_resolve_storage_engine_name(*new_engine),
6732
                       table_name);
6733
  }
6734
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
6735
      ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
6736
  {
6737
    if (create_info->used_fields & HA_CREATE_USED_ENGINE)
6738
    {
6739
      my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
6740
               ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
6741
      *new_engine= 0;
6742
      return TRUE;
6743
    }
6744
    *new_engine= myisam_hton;
6745
  }
6746
  return FALSE;
6747
}