~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_table.cc

MergingĀ mainline

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* drop and alter of tables */
17
17
 
18
 
#include <drizzled/server_includes.h>
19
 
#include <storage/myisam/myisam.h>
20
 
#include <drizzled/sql_show.h>
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
#include <libdrizzle/gettext.h>
 
18
#include "mysql_priv.h"
 
19
#include <hash.h>
 
20
#include <myisam.h>
 
21
#include <my_dir.h>
 
22
#include "sql_show.h"
23
23
 
24
24
int creating_table= 0;        // How many mysql_create_table are running
25
25
 
27
27
 
28
28
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
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,
 
30
static int copy_data_between_tables(TABLE *from,TABLE *to,
31
31
                                    List<Create_field> &create, bool ignore,
32
 
                                    uint32_t order_num, order_st *order,
 
32
                                    uint order_num, ORDER *order,
33
33
                                    ha_rows *copied,ha_rows *deleted,
34
34
                                    enum enum_enable_or_disable keys_onoff,
35
35
                                    bool error_if_not_empty);
40
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
41
41
                           Alter_info *alter_info,
42
42
                           bool tmp_table,
43
 
                               uint32_t *db_options,
 
43
                               uint *db_options,
44
44
                               handler *file, KEY **key_info_buffer,
45
 
                               uint32_t *key_count, int select_field_count);
 
45
                               uint *key_count, int select_field_count);
46
46
static bool
47
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
47
mysql_prepare_alter_table(THD *thd, TABLE *table,
48
48
                          HA_CREATE_INFO *create_info,
49
49
                          Alter_info *alter_info);
50
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
 
51
65
/*
52
66
  Translate a file name to a table name (WL #1324).
53
67
 
60
74
  RETURN
61
75
    Table name length.
62
76
*/
63
 
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
 
77
 
 
78
uint filename_to_tablename(const char *from, char *to, uint to_length)
64
79
{
65
 
  uint32_t errors;
66
 
  uint32_t res;
 
80
  uint errors;
 
81
  uint res;
67
82
 
68
83
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
69
84
  {
70
85
    /* Temporary table name. */
71
 
    res= (my_stpncpy(to, from, to_length) - to);
 
86
    res= (strnmov(to, from, to_length) - to);
72
87
  }
73
88
  else
74
89
  {
76
91
                    system_charset_info,  to, to_length, &errors);
77
92
    if (errors) // Old 5.0 name
78
93
    {
79
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NULL) -
 
94
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
80
95
            to);
81
 
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
 
96
      sql_print_error("Invalid (old?) table or database name '%s'", from);
 
97
      /*
 
98
        TODO: add a stored procedure for fix table and database names,
 
99
        and mention its name in error log.
 
100
      */
82
101
    }
83
102
  }
84
103
 
99
118
    File name length.
100
119
*/
101
120
 
102
 
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
 
121
uint tablename_to_filename(const char *from, char *to, uint to_length)
103
122
{
104
 
  uint32_t errors, length;
 
123
  uint errors, length;
105
124
 
106
125
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
107
126
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
143
162
    'db' is always converted.
144
163
    'ext' is not converted.
145
164
 
146
 
    The conversion suppression is required for ALTER Table. This
 
165
    The conversion suppression is required for ALTER TABLE. This
147
166
    statement creates intermediate tables. These are regular
148
167
    (non-temporary) tables with a temporary name. Their path names must
149
168
    be derivable from the table name. So we cannot use
153
172
    path length
154
173
*/
155
174
 
156
 
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
157
 
                          const char *table_name, const char *ext, uint32_t flags)
 
175
uint build_table_filename(char *buff, size_t bufflen, const char *db,
 
176
                          const char *table_name, const char *ext, uint flags)
158
177
{
159
178
  char dbbuff[FN_REFLEN];
160
179
  char tbbuff[FN_REFLEN];
161
180
 
162
181
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
 
    my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
 
182
    strnmov(tbbuff, table_name, sizeof(tbbuff));
164
183
  else
165
 
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
 
184
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
166
185
 
167
 
  tablename_to_filename(db, dbbuff, sizeof(dbbuff));
 
186
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
168
187
 
169
188
  char *end = buff + bufflen;
170
189
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
171
 
  char *pos = my_stpncpy(buff, mysql_data_home, bufflen);
 
190
  char *pos = strnmov(buff, mysql_data_home, bufflen);
172
191
  int rootdir_len= strlen(FN_ROOTDIR);
173
192
  if (pos - rootdir_len >= buff &&
174
193
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
175
 
    pos= my_stpncpy(pos, FN_ROOTDIR, end - pos);
176
 
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NULL);
 
194
    pos= strnmov(pos, FN_ROOTDIR, end - pos);
 
195
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
177
196
#ifdef USE_SYMDIR
178
197
  unpack_dirname(buff, buff);
179
198
  pos= strend(buff);
180
199
#endif
181
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
 
200
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
182
201
 
183
202
  return(pos - buff);
184
203
}
202
221
    path length
203
222
*/
204
223
 
205
 
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
224
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
206
225
{
207
226
 
208
 
  char *p= my_stpncpy(buff, mysql_tmpdir, bufflen);
 
227
  char *p= strnmov(buff, mysql_tmpdir, bufflen);
209
228
  snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
210
229
              tmp_file_prefix, current_pid,
211
230
              thd->thread_id, thd->tmp_table++, reg_ext);
216
235
    my_casedn_str(files_charset_info, p);
217
236
  }
218
237
 
219
 
  uint32_t length= unpack_filename(buff, buff);
 
238
  uint length= unpack_filename(buff, buff);
220
239
  return(length);
221
240
}
222
241
 
223
242
/*
 
243
--------------------------------------------------------------------------
 
244
 
 
245
   MODULE: DDL log
 
246
   -----------------
 
247
 
 
248
   This module is used to ensure that we can recover from crashes that occur
 
249
   in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
 
250
   We need to ensure that both t1 and t2 are dropped and not only t1 and
 
251
   also that each table drop is entirely done and not "half-baked".
 
252
 
 
253
   To support this we create log entries for each meta-data statement in the
 
254
   ddl log while we are executing. These entries are dropped when the
 
255
   operation is completed.
 
256
 
 
257
   At recovery those entries that were not completed will be executed.
 
258
 
 
259
   There is only one ddl log in the system and it is protected by a mutex
 
260
   and there is a global struct that contains information about its current
 
261
   state.
 
262
 
 
263
   History:
 
264
   First version written in 2006 by Mikael Ronstrom
 
265
--------------------------------------------------------------------------
 
266
*/
 
267
 
 
268
 
 
269
struct st_global_ddl_log
 
270
{
 
271
  /*
 
272
    We need to adjust buffer size to be able to handle downgrades/upgrades
 
273
    where IO_SIZE has changed. We'll set the buffer size such that we can
 
274
    handle that the buffer size was upto 4 times bigger in the version
 
275
    that wrote the DDL log.
 
276
  */
 
277
  char file_entry_buf[4*IO_SIZE];
 
278
  char file_name_str[FN_REFLEN];
 
279
  char *file_name;
 
280
  DDL_LOG_MEMORY_ENTRY *first_free;
 
281
  DDL_LOG_MEMORY_ENTRY *first_used;
 
282
  uint num_entries;
 
283
  File file_id;
 
284
  uint name_len;
 
285
  uint io_size;
 
286
  bool inited;
 
287
  bool do_release;
 
288
  bool recovery_phase;
 
289
  st_global_ddl_log() : inited(false), do_release(false) {}
 
290
};
 
291
 
 
292
st_global_ddl_log global_ddl_log;
 
293
 
 
294
pthread_mutex_t LOCK_gdl;
 
295
 
 
296
#define DDL_LOG_ENTRY_TYPE_POS 0
 
297
#define DDL_LOG_ACTION_TYPE_POS 1
 
298
#define DDL_LOG_PHASE_POS 2
 
299
#define DDL_LOG_NEXT_ENTRY_POS 4
 
300
#define DDL_LOG_NAME_POS 8
 
301
 
 
302
#define DDL_LOG_NUM_ENTRY_POS 0
 
303
#define DDL_LOG_NAME_LEN_POS 4
 
304
#define DDL_LOG_IO_SIZE_POS 8
 
305
 
 
306
/*
 
307
  Read one entry from ddl log file
 
308
  SYNOPSIS
 
309
    read_ddl_log_file_entry()
 
310
    entry_no                     Entry number to read
 
311
  RETURN VALUES
 
312
    true                         Error
 
313
    false                        Success
 
314
*/
 
315
 
 
316
static bool read_ddl_log_file_entry(uint entry_no)
 
317
{
 
318
  bool error= false;
 
319
  File file_id= global_ddl_log.file_id;
 
320
  uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
 
321
  ssize_t io_size= (ssize_t)global_ddl_log.io_size;
 
322
  
 
323
  if (pread(file_id, file_entry_buf, io_size, io_size * entry_no) != io_size)
 
324
    error= true;
 
325
  return(error);
 
326
}
 
327
 
 
328
 
 
329
/*
 
330
  Write one entry from ddl log file
 
331
  SYNOPSIS
 
332
    write_ddl_log_file_entry()
 
333
    entry_no                     Entry number to read
 
334
  RETURN VALUES
 
335
    true                         Error
 
336
    false                        Success
 
337
*/
 
338
 
 
339
static bool write_ddl_log_file_entry(uint entry_no)
 
340
{
 
341
  bool error= false;
 
342
  File file_id= global_ddl_log.file_id;
 
343
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
344
 
 
345
  if (pwrite(file_id, (uchar*)file_entry_buf,
 
346
                IO_SIZE, IO_SIZE * entry_no) != IO_SIZE)
 
347
    error= true;
 
348
  return(error);
 
349
}
 
350
 
 
351
 
 
352
/*
 
353
  Write ddl log header
 
354
  SYNOPSIS
 
355
    write_ddl_log_header()
 
356
  RETURN VALUES
 
357
    true                      Error
 
358
    false                     Success
 
359
*/
 
360
 
 
361
static bool write_ddl_log_header()
 
362
{
 
363
  uint16 const_var;
 
364
  bool error= false;
 
365
 
 
366
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
 
367
            global_ddl_log.num_entries);
 
368
  const_var= FN_LEN;
 
369
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
 
370
            (ulong) const_var);
 
371
  const_var= IO_SIZE;
 
372
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
 
373
            (ulong) const_var);
 
374
  if (write_ddl_log_file_entry(0UL))
 
375
  {
 
376
    sql_print_error("Error writing ddl log header");
 
377
    return(true);
 
378
  }
 
379
  VOID(sync_ddl_log());
 
380
  return(error);
 
381
}
 
382
 
 
383
 
 
384
/*
 
385
  Create ddl log file name
 
386
  SYNOPSIS
 
387
    create_ddl_log_file_name()
 
388
    file_name                   Filename setup
 
389
  RETURN VALUES
 
390
    NONE
 
391
*/
 
392
 
 
393
static inline void create_ddl_log_file_name(char *file_name)
 
394
{
 
395
  strxmov(file_name, mysql_data_home, "/", "ddl_log.log", NullS);
 
396
}
 
397
 
 
398
 
 
399
/*
 
400
  Read header of ddl log file
 
401
  SYNOPSIS
 
402
    read_ddl_log_header()
 
403
  RETURN VALUES
 
404
    > 0                  Last entry in ddl log
 
405
    0                    No entries in ddl log
 
406
  DESCRIPTION
 
407
    When we read the ddl log header we get information about maximum sizes
 
408
    of names in the ddl log and we also get information about the number
 
409
    of entries in the ddl log.
 
410
*/
 
411
 
 
412
static uint read_ddl_log_header()
 
413
{
 
414
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
415
  char file_name[FN_REFLEN];
 
416
  uint entry_no;
 
417
  bool successful_open= false;
 
418
 
 
419
  create_ddl_log_file_name(file_name);
 
420
  if ((global_ddl_log.file_id= my_open(file_name,
 
421
                                        O_RDWR | O_BINARY, MYF(0))) >= 0)
 
422
  {
 
423
    if (read_ddl_log_file_entry(0UL))
 
424
    {
 
425
      /* Write message into error log */
 
426
      sql_print_error("Failed to read ddl log file in recovery");
 
427
    }
 
428
    else
 
429
      successful_open= true;
 
430
  }
 
431
  entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
 
432
  global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
 
433
  if (successful_open)
 
434
  {
 
435
    global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
 
436
    assert(global_ddl_log.io_size <=
 
437
                sizeof(global_ddl_log.file_entry_buf));
 
438
  }
 
439
  else
 
440
  {
 
441
    entry_no= 0;
 
442
  }
 
443
  global_ddl_log.first_free= NULL;
 
444
  global_ddl_log.first_used= NULL;
 
445
  global_ddl_log.num_entries= 0;
 
446
  VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
 
447
  global_ddl_log.do_release= true;
 
448
  return(entry_no);
 
449
}
 
450
 
 
451
 
 
452
/*
 
453
  Read a ddl log entry
 
454
  SYNOPSIS
 
455
    read_ddl_log_entry()
 
456
    read_entry               Number of entry to read
 
457
    out:entry_info           Information from entry
 
458
  RETURN VALUES
 
459
    true                     Error
 
460
    false                    Success
 
461
  DESCRIPTION
 
462
    Read a specified entry in the ddl log
 
463
*/
 
464
 
 
465
bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
 
466
{
 
467
  char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
 
468
  uint inx;
 
469
  uchar single_char;
 
470
 
 
471
  if (read_ddl_log_file_entry(read_entry))
 
472
  {
 
473
    return(true);
 
474
  }
 
475
  ddl_log_entry->entry_pos= read_entry;
 
476
  single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
 
477
  ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
 
478
  single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
 
479
  ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
 
480
  ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
 
481
  ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
 
482
  ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
 
483
  inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
 
484
  ddl_log_entry->from_name= &file_entry_buf[inx];
 
485
  inx+= global_ddl_log.name_len;
 
486
  ddl_log_entry->handler_name= &file_entry_buf[inx];
 
487
  return(false);
 
488
}
 
489
 
 
490
 
 
491
/*
 
492
  Initialise ddl log
 
493
  SYNOPSIS
 
494
    init_ddl_log()
 
495
 
 
496
  DESCRIPTION
 
497
    Write the header of the ddl log file and length of names. Also set
 
498
    number of entries to zero.
 
499
 
 
500
  RETURN VALUES
 
501
    true                     Error
 
502
    false                    Success
 
503
*/
 
504
 
 
505
static bool init_ddl_log()
 
506
{
 
507
  char file_name[FN_REFLEN];
 
508
 
 
509
  if (global_ddl_log.inited)
 
510
    goto end;
 
511
 
 
512
  global_ddl_log.io_size= IO_SIZE;
 
513
  create_ddl_log_file_name(file_name);
 
514
  if ((global_ddl_log.file_id= my_create(file_name,
 
515
                                         CREATE_MODE,
 
516
                                         O_RDWR | O_TRUNC | O_BINARY,
 
517
                                         MYF(MY_WME))) < 0)
 
518
  {
 
519
    /* Couldn't create ddl log file, this is serious error */
 
520
    sql_print_error("Failed to open ddl log file");
 
521
    return(true);
 
522
  }
 
523
  global_ddl_log.inited= true;
 
524
  if (write_ddl_log_header())
 
525
  {
 
526
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
 
527
    global_ddl_log.inited= false;
 
528
    return(true);
 
529
  }
 
530
 
 
531
end:
 
532
  return(false);
 
533
}
 
534
 
 
535
 
 
536
/*
 
537
  Execute one action in a ddl log entry
 
538
  SYNOPSIS
 
539
    execute_ddl_log_action()
 
540
    ddl_log_entry              Information in action entry to execute
 
541
  RETURN VALUES
 
542
    true                       Error
 
543
    false                      Success
 
544
*/
 
545
 
 
546
static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
 
547
{
 
548
  bool frm_action= false;
 
549
  LEX_STRING handler_name;
 
550
  handler *file= NULL;
 
551
  MEM_ROOT mem_root;
 
552
  int error= true;
 
553
  char to_path[FN_REFLEN];
 
554
  char from_path[FN_REFLEN];
 
555
  handlerton *hton;
 
556
 
 
557
  if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
 
558
  {
 
559
    return(false);
 
560
  }
 
561
  handler_name.str= (char*)ddl_log_entry->handler_name;
 
562
  handler_name.length= strlen(ddl_log_entry->handler_name);
 
563
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 
 
564
  if (!strcmp(ddl_log_entry->handler_name, reg_ext))
 
565
    frm_action= true;
 
566
  else
 
567
  {
 
568
    plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
 
569
    if (!plugin)
 
570
    {
 
571
      my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
 
572
      goto error;
 
573
    }
 
574
    hton= plugin_data(plugin, handlerton*);
 
575
    file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
 
576
    if (!file)
 
577
    {
 
578
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
 
579
      goto error;
 
580
    }
 
581
  }
 
582
  switch (ddl_log_entry->action_type)
 
583
  {
 
584
    case DDL_LOG_REPLACE_ACTION:
 
585
    case DDL_LOG_DELETE_ACTION:
 
586
    {
 
587
      if (ddl_log_entry->phase == 0)
 
588
      {
 
589
        if (frm_action)
 
590
        {
 
591
          strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
 
592
          if ((error= my_delete(to_path, MYF(MY_WME))))
 
593
          {
 
594
            if (my_errno != ENOENT)
 
595
              break;
 
596
          }
 
597
        }
 
598
        else
 
599
        {
 
600
          if ((error= file->ha_delete_table(ddl_log_entry->name)))
 
601
          {
 
602
            if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
 
603
              break;
 
604
          }
 
605
        }
 
606
        if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
 
607
          break;
 
608
        VOID(sync_ddl_log());
 
609
        error= false;
 
610
        if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
 
611
          break;
 
612
      }
 
613
      assert(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
 
614
      /*
 
615
        Fall through and perform the rename action of the replace
 
616
        action. We have already indicated the success of the delete
 
617
        action in the log entry by stepping up the phase.
 
618
      */
 
619
    }
 
620
    case DDL_LOG_RENAME_ACTION:
 
621
    {
 
622
      error= true;
 
623
      if (frm_action)
 
624
      {
 
625
        strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
 
626
        strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
 
627
        if (my_rename(from_path, to_path, MYF(MY_WME)))
 
628
          break;
 
629
      }
 
630
      else
 
631
      {
 
632
        if (file->ha_rename_table(ddl_log_entry->from_name,
 
633
                                  ddl_log_entry->name))
 
634
          break;
 
635
      }
 
636
      if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
 
637
        break;
 
638
      VOID(sync_ddl_log());
 
639
      error= false;
 
640
      break;
 
641
    }
 
642
    default:
 
643
      assert(0);
 
644
      break;
 
645
  }
 
646
  delete file;
 
647
error:
 
648
  free_root(&mem_root, MYF(0)); 
 
649
  return(error);
 
650
}
 
651
 
 
652
 
 
653
/*
 
654
  Get a free entry in the ddl log
 
655
  SYNOPSIS
 
656
    get_free_ddl_log_entry()
 
657
    out:active_entry                A ddl log memory entry returned
 
658
  RETURN VALUES
 
659
    true                       Error
 
660
    false                      Success
 
661
*/
 
662
 
 
663
static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
 
664
                                   bool *write_header)
 
665
{
 
666
  DDL_LOG_MEMORY_ENTRY *used_entry;
 
667
  DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
 
668
 
 
669
  if (global_ddl_log.first_free == NULL)
 
670
  {
 
671
    if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
 
672
                              sizeof(DDL_LOG_MEMORY_ENTRY), MYF(MY_WME))))
 
673
    {
 
674
      sql_print_error("Failed to allocate memory for ddl log free list");
 
675
      return(true);
 
676
    }
 
677
    global_ddl_log.num_entries++;
 
678
    used_entry->entry_pos= global_ddl_log.num_entries;
 
679
    *write_header= true;
 
680
  }
 
681
  else
 
682
  {
 
683
    used_entry= global_ddl_log.first_free;
 
684
    global_ddl_log.first_free= used_entry->next_log_entry;
 
685
    *write_header= false;
 
686
  }
 
687
  /*
 
688
    Move from free list to used list
 
689
  */
 
690
  used_entry->next_log_entry= first_used;
 
691
  used_entry->prev_log_entry= NULL;
 
692
  global_ddl_log.first_used= used_entry;
 
693
  if (first_used)
 
694
    first_used->prev_log_entry= used_entry;
 
695
 
 
696
  *active_entry= used_entry;
 
697
  return(false);
 
698
}
 
699
 
 
700
 
 
701
/*
 
702
  External interface methods for the DDL log Module
 
703
  ---------------------------------------------------
 
704
*/
 
705
 
 
706
/*
 
707
  SYNOPSIS
 
708
    write_ddl_log_entry()
 
709
    ddl_log_entry         Information about log entry
 
710
    out:entry_written     Entry information written into   
 
711
 
 
712
  RETURN VALUES
 
713
    true                      Error
 
714
    false                     Success
 
715
 
 
716
  DESCRIPTION
 
717
    A careful write of the ddl log is performed to ensure that we can
 
718
    handle crashes occurring during CREATE and ALTER TABLE processing.
 
719
*/
 
720
 
 
721
bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
 
722
                         DDL_LOG_MEMORY_ENTRY **active_entry)
 
723
{
 
724
  bool error, write_header;
 
725
 
 
726
  if (init_ddl_log())
 
727
  {
 
728
    return(true);
 
729
  }
 
730
  global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
 
731
                                    (char)DDL_LOG_ENTRY_CODE;
 
732
  global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
 
733
                                    (char)ddl_log_entry->action_type;
 
734
  global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
 
735
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
 
736
            ddl_log_entry->next_entry);
 
737
  assert(strlen(ddl_log_entry->name) < FN_LEN);
 
738
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
 
739
          ddl_log_entry->name, FN_LEN - 1);
 
740
  if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
 
741
      ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
 
742
  {
 
743
    assert(strlen(ddl_log_entry->from_name) < FN_LEN);
 
744
    strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
 
745
          ddl_log_entry->from_name, FN_LEN - 1);
 
746
  }
 
747
  else
 
748
    global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
 
749
  assert(strlen(ddl_log_entry->handler_name) < FN_LEN);
 
750
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
 
751
          ddl_log_entry->handler_name, FN_LEN - 1);
 
752
  if (get_free_ddl_log_entry(active_entry, &write_header))
 
753
  {
 
754
    return(true);
 
755
  }
 
756
  error= false;
 
757
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
 
758
  {
 
759
    error= true;
 
760
    sql_print_error("Failed to write entry_no = %u",
 
761
                    (*active_entry)->entry_pos);
 
762
  }
 
763
  if (write_header && !error)
 
764
  {
 
765
    VOID(sync_ddl_log());
 
766
    if (write_ddl_log_header())
 
767
      error= true;
 
768
  }
 
769
  if (error)
 
770
    release_ddl_log_memory_entry(*active_entry);
 
771
  return(error);
 
772
}
 
773
 
 
774
 
 
775
/*
 
776
  Write final entry in the ddl log
 
777
  SYNOPSIS
 
778
    write_execute_ddl_log_entry()
 
779
    first_entry                    First entry in linked list of entries
 
780
                                   to execute, if 0 = NULL it means that
 
781
                                   the entry is removed and the entries
 
782
                                   are put into the free list.
 
783
    complete                       Flag indicating we are simply writing
 
784
                                   info about that entry has been completed
 
785
    in:out:active_entry            Entry to execute, 0 = NULL if the entry
 
786
                                   is written first time and needs to be
 
787
                                   returned. In this case the entry written
 
788
                                   is returned in this parameter
 
789
  RETURN VALUES
 
790
    true                           Error
 
791
    false                          Success
 
792
 
 
793
  DESCRIPTION
 
794
    This is the last write in the ddl log. The previous log entries have
 
795
    already been written but not yet synched to disk.
 
796
    We write a couple of log entries that describes action to perform.
 
797
    This entries are set-up in a linked list, however only when a first
 
798
    execute entry is put as the first entry these will be executed.
 
799
    This routine writes this first 
 
800
*/ 
 
801
 
 
802
bool write_execute_ddl_log_entry(uint first_entry,
 
803
                                 bool complete,
 
804
                                 DDL_LOG_MEMORY_ENTRY **active_entry)
 
805
{
 
806
  bool write_header= false;
 
807
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
808
 
 
809
  if (init_ddl_log())
 
810
  {
 
811
    return(true);
 
812
  }
 
813
  if (!complete)
 
814
  {
 
815
    /*
 
816
      We haven't synched the log entries yet, we synch them now before
 
817
      writing the execute entry. If complete is true we haven't written
 
818
      any log entries before, we are only here to write the execute
 
819
      entry to indicate it is done.
 
820
    */
 
821
    VOID(sync_ddl_log());
 
822
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
 
823
  }
 
824
  else
 
825
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
 
826
  file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
 
827
  file_entry_buf[DDL_LOG_PHASE_POS]= 0;
 
828
  int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
 
829
  file_entry_buf[DDL_LOG_NAME_POS]= 0;
 
830
  file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
 
831
  file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
 
832
  if (!(*active_entry))
 
833
  {
 
834
    if (get_free_ddl_log_entry(active_entry, &write_header))
 
835
    {
 
836
      return(true);
 
837
    }
 
838
  }
 
839
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
 
840
  {
 
841
    sql_print_error("Error writing execute entry in ddl log");
 
842
    release_ddl_log_memory_entry(*active_entry);
 
843
    return(true);
 
844
  }
 
845
  VOID(sync_ddl_log());
 
846
  if (write_header)
 
847
  {
 
848
    if (write_ddl_log_header())
 
849
    {
 
850
      release_ddl_log_memory_entry(*active_entry);
 
851
      return(true);
 
852
    }
 
853
  }
 
854
  return(false);
 
855
}
 
856
 
 
857
 
 
858
/*
 
859
  For complex rename operations we need to deactivate individual entries.
 
860
  SYNOPSIS
 
861
    deactivate_ddl_log_entry()
 
862
    entry_no                      Entry position of record to change
 
863
  RETURN VALUES
 
864
    true                         Error
 
865
    false                        Success
 
866
  DESCRIPTION
 
867
    During replace operations where we start with an existing table called
 
868
    t1 and a replacement table called t1#temp or something else and where
 
869
    we want to delete t1 and rename t1#temp to t1 this is not possible to
 
870
    do in a safe manner unless the ddl log is informed of the phases in
 
871
    the change.
 
872
 
 
873
    Delete actions are 1-phase actions that can be ignored immediately after
 
874
    being executed.
 
875
    Rename actions from x to y is also a 1-phase action since there is no
 
876
    interaction with any other handlers named x and y.
 
877
    Replace action where drop y and x -> y happens needs to be a two-phase
 
878
    action. Thus the first phase will drop y and the second phase will
 
879
    rename x -> y.
 
880
*/
 
881
 
 
882
bool deactivate_ddl_log_entry(uint entry_no)
 
883
{
 
884
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
885
 
 
886
  if (!read_ddl_log_file_entry(entry_no))
 
887
  {
 
888
    if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
 
889
    {
 
890
      if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
 
891
          file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
 
892
          (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
 
893
           file_entry_buf[DDL_LOG_PHASE_POS] == 1))
 
894
        file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
 
895
      else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
 
896
      {
 
897
        assert(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
 
898
        file_entry_buf[DDL_LOG_PHASE_POS]= 1;
 
899
      }
 
900
      else
 
901
      {
 
902
        assert(0);
 
903
      }
 
904
      if (write_ddl_log_file_entry(entry_no))
 
905
      {
 
906
        sql_print_error("Error in deactivating log entry. Position = %u",
 
907
                        entry_no);
 
908
        return(true);
 
909
      }
 
910
    }
 
911
  }
 
912
  else
 
913
  {
 
914
    sql_print_error("Failed in reading entry before deactivating it");
 
915
    return(true);
 
916
  }
 
917
  return(false);
 
918
}
 
919
 
 
920
 
 
921
/*
 
922
  Sync ddl log file
 
923
  SYNOPSIS
 
924
    sync_ddl_log()
 
925
  RETURN VALUES
 
926
    true                      Error
 
927
    false                     Success
 
928
*/
 
929
 
 
930
bool sync_ddl_log()
 
931
{
 
932
  bool error= false;
 
933
 
 
934
  if ((!global_ddl_log.recovery_phase) &&
 
935
      init_ddl_log())
 
936
  {
 
937
    return(true);
 
938
  }
 
939
  if (my_sync(global_ddl_log.file_id, MYF(0)))
 
940
  {
 
941
    /* Write to error log */
 
942
    sql_print_error("Failed to sync ddl log");
 
943
    error= true;
 
944
  }
 
945
  return(error);
 
946
}
 
947
 
 
948
 
 
949
/*
 
950
  Release a log memory entry
 
951
  SYNOPSIS
 
952
    release_ddl_log_memory_entry()
 
953
    log_memory_entry                Log memory entry to release
 
954
  RETURN VALUES
 
955
    NONE
 
956
*/
 
957
 
 
958
void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
 
959
{
 
960
  DDL_LOG_MEMORY_ENTRY *first_free= global_ddl_log.first_free;
 
961
  DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
 
962
  DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
 
963
 
 
964
  global_ddl_log.first_free= log_entry;
 
965
  log_entry->next_log_entry= first_free;
 
966
 
 
967
  if (prev_log_entry)
 
968
    prev_log_entry->next_log_entry= next_log_entry;
 
969
  else
 
970
    global_ddl_log.first_used= next_log_entry;
 
971
  if (next_log_entry)
 
972
    next_log_entry->prev_log_entry= prev_log_entry;
 
973
  return;
 
974
}
 
975
 
 
976
 
 
977
/*
 
978
  Execute one entry in the ddl log. Executing an entry means executing
 
979
  a linked list of actions.
 
980
  SYNOPSIS
 
981
    execute_ddl_log_entry()
 
982
    first_entry                Reference to first action in entry
 
983
  RETURN VALUES
 
984
    true                       Error
 
985
    false                      Success
 
986
*/
 
987
 
 
988
bool execute_ddl_log_entry(THD *thd, uint first_entry)
 
989
{
 
990
  DDL_LOG_ENTRY ddl_log_entry;
 
991
  uint read_entry= first_entry;
 
992
 
 
993
  pthread_mutex_lock(&LOCK_gdl);
 
994
  do
 
995
  {
 
996
    if (read_ddl_log_entry(read_entry, &ddl_log_entry))
 
997
    {
 
998
      /* Write to error log and continue with next log entry */
 
999
      sql_print_error("Failed to read entry = %u from ddl log",
 
1000
                      read_entry);
 
1001
      break;
 
1002
    }
 
1003
    assert(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
 
1004
                ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
 
1005
 
 
1006
    if (execute_ddl_log_action(thd, &ddl_log_entry))
 
1007
    {
 
1008
      /* Write to error log and continue with next log entry */
 
1009
      sql_print_error("Failed to execute action for entry = %u from ddl log",
 
1010
                      read_entry);
 
1011
      break;
 
1012
    }
 
1013
    read_entry= ddl_log_entry.next_entry;
 
1014
  } while (read_entry);
 
1015
  pthread_mutex_unlock(&LOCK_gdl);
 
1016
  return(false);
 
1017
}
 
1018
 
 
1019
 
 
1020
/*
 
1021
  Close the ddl log
 
1022
  SYNOPSIS
 
1023
    close_ddl_log()
 
1024
  RETURN VALUES
 
1025
    NONE
 
1026
*/
 
1027
 
 
1028
static void close_ddl_log()
 
1029
{
 
1030
  if (global_ddl_log.file_id >= 0)
 
1031
  {
 
1032
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
 
1033
    global_ddl_log.file_id= (File) -1;
 
1034
  }
 
1035
  return;
 
1036
}
 
1037
 
 
1038
 
 
1039
/*
 
1040
  Execute the ddl log at recovery of MySQL Server
 
1041
  SYNOPSIS
 
1042
    execute_ddl_log_recovery()
 
1043
  RETURN VALUES
 
1044
    NONE
 
1045
*/
 
1046
 
 
1047
void execute_ddl_log_recovery()
 
1048
{
 
1049
  uint num_entries, i;
 
1050
  THD *thd;
 
1051
  DDL_LOG_ENTRY ddl_log_entry;
 
1052
  char file_name[FN_REFLEN];
 
1053
 
 
1054
  /*
 
1055
    Initialise global_ddl_log struct
 
1056
  */
 
1057
  bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
 
1058
  global_ddl_log.inited= false;
 
1059
  global_ddl_log.recovery_phase= true;
 
1060
  global_ddl_log.io_size= IO_SIZE;
 
1061
  global_ddl_log.file_id= (File) -1;
 
1062
 
 
1063
  /*
 
1064
    To be able to run this from boot, we allocate a temporary THD
 
1065
  */
 
1066
  if (!(thd=new THD))
 
1067
    return;
 
1068
  thd->thread_stack= (char*) &thd;
 
1069
  thd->store_globals();
 
1070
 
 
1071
  num_entries= read_ddl_log_header();
 
1072
  for (i= 1; i < num_entries + 1; i++)
 
1073
  {
 
1074
    if (read_ddl_log_entry(i, &ddl_log_entry))
 
1075
    {
 
1076
      sql_print_error("Failed to read entry no = %u from ddl log",
 
1077
                       i);
 
1078
      continue;
 
1079
    }
 
1080
    if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
 
1081
    {
 
1082
      if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
 
1083
      {
 
1084
        /* Real unpleasant scenario but we continue anyways.  */
 
1085
        continue;
 
1086
      }
 
1087
    }
 
1088
  }
 
1089
  close_ddl_log();
 
1090
  create_ddl_log_file_name(file_name);
 
1091
  VOID(my_delete(file_name, MYF(0)));
 
1092
  global_ddl_log.recovery_phase= false;
 
1093
  delete thd;
 
1094
  /* Remember that we don't have a THD */
 
1095
  my_pthread_setspecific_ptr(THR_THD,  0);
 
1096
  return;
 
1097
}
 
1098
 
 
1099
 
 
1100
/*
 
1101
  Release all memory allocated to the ddl log
 
1102
  SYNOPSIS
 
1103
    release_ddl_log()
 
1104
  RETURN VALUES
 
1105
    NONE
 
1106
*/
 
1107
 
 
1108
void release_ddl_log()
 
1109
{
 
1110
  DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
 
1111
  DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
 
1112
 
 
1113
  if (!global_ddl_log.do_release)
 
1114
    return;
 
1115
 
 
1116
  pthread_mutex_lock(&LOCK_gdl);
 
1117
  while (used_list)
 
1118
  {
 
1119
    DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
 
1120
    my_free(used_list, MYF(0));
 
1121
    used_list= tmp;
 
1122
  }
 
1123
  while (free_list)
 
1124
  {
 
1125
    DDL_LOG_MEMORY_ENTRY *tmp= free_list->next_log_entry;
 
1126
    my_free(free_list, MYF(0));
 
1127
    free_list= tmp;
 
1128
  }
 
1129
  close_ddl_log();
 
1130
  global_ddl_log.inited= 0;
 
1131
  pthread_mutex_unlock(&LOCK_gdl);
 
1132
  VOID(pthread_mutex_destroy(&LOCK_gdl));
 
1133
  global_ddl_log.do_release= false;
 
1134
  return;
 
1135
}
 
1136
 
 
1137
 
 
1138
/*
 
1139
---------------------------------------------------------------------------
 
1140
 
 
1141
  END MODULE DDL log
 
1142
  --------------------
 
1143
 
 
1144
---------------------------------------------------------------------------
 
1145
*/
 
1146
 
 
1147
 
 
1148
/*
224
1149
  SYNOPSIS
225
1150
    write_bin_log()
226
1151
    thd                           Thread object
273
1198
 
274
1199
*/
275
1200
 
276
 
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
 
1201
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
 
1202
                    my_bool drop_temporary)
277
1203
{
278
1204
  bool error, need_start_waiting= false;
279
1205
 
338
1264
   -1   Thread was killed
339
1265
*/
340
1266
 
341
 
int mysql_rm_table_part2(THD *thd, TableList *tables, bool if_exists,
 
1267
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
342
1268
                         bool drop_temporary, bool drop_view,
343
1269
                         bool dont_log_query)
344
1270
{
345
 
  TableList *table;
 
1271
  TABLE_LIST *table;
346
1272
  char path[FN_REFLEN], *alias;
347
 
  uint32_t path_length;
 
1273
  uint path_length;
348
1274
  String wrong_tables;
349
1275
  int error= 0;
350
1276
  int non_temp_tables_count= 0;
355
1281
  {
356
1282
    built_query.set_charset(system_charset_info);
357
1283
    if (if_exists)
358
 
      built_query.append("DROP Table IF EXISTS ");
 
1284
      built_query.append("DROP TABLE IF EXISTS ");
359
1285
    else
360
 
      built_query.append("DROP Table ");
 
1286
      built_query.append("DROP TABLE ");
361
1287
  }
362
1288
 
363
1289
  mysql_ha_rm_tables(thd, tables, false);
402
1328
      tmp_table_deleted= 1;
403
1329
      continue;
404
1330
    case -1:
 
1331
      assert(thd->in_sub_stmt);
405
1332
      error= 1;
406
1333
      goto err_with_placeholders;
407
1334
    default:
436
1363
    table_type= table->db_type;
437
1364
    if (!drop_temporary)
438
1365
    {
439
 
      Table *locked_table;
 
1366
      TABLE *locked_table;
440
1367
      abort_locked_tables(thd, db, table->table_name);
441
1368
      remove_table_from_cache(thd, db, table->table_name,
442
1369
                              RTFC_WAIT_OTHER_THREAD_FLAG |
461
1388
    }
462
1389
    if (drop_temporary ||
463
1390
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
464
 
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != true)))
 
1391
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
465
1392
    {
466
1393
      // Table was not found on disk and table can't be created from engine
467
1394
      if (if_exists)
468
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1395
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
469
1396
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
470
1397
                            table->table_name);
471
1398
      else
498
1425
      {
499
1426
        int new_error;
500
1427
        /* Delete the table definition file */
501
 
        my_stpcpy(end,reg_ext);
 
1428
        strmov(end,reg_ext);
502
1429
        if (!(new_error=my_delete(path,MYF(MY_WME))))
503
1430
        {
504
1431
          some_tables_deleted=1;
527
1454
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
528
1455
                      wrong_tables.c_ptr());
529
1456
    else
530
 
    {
531
1457
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
532
 
    }
533
1458
    error= 1;
534
1459
  }
535
1460
 
581
1506
  }
582
1507
  pthread_mutex_lock(&LOCK_open);
583
1508
err_with_placeholders:
584
 
  unlock_table_names(thd, tables, (TableList*) 0);
 
1509
  unlock_table_names(thd, tables, (TABLE_LIST*) 0);
585
1510
  pthread_mutex_unlock(&LOCK_open);
586
1511
  thd->no_warnings_for_error= 0;
587
1512
  return(error);
604
1529
*/
605
1530
 
606
1531
bool quick_rm_table(handlerton *base,const char *db,
607
 
                    const char *table_name, uint32_t flags)
 
1532
                    const char *table_name, uint flags)
608
1533
{
609
1534
  char path[FN_REFLEN];
610
1535
  bool error= 0;
611
1536
 
612
 
  uint32_t path_length= build_table_filename(path, sizeof(path),
 
1537
  uint path_length= build_table_filename(path, sizeof(path),
613
1538
                                         db, table_name, reg_ext, flags);
614
1539
  if (my_delete(path,MYF(0)))
615
1540
    error= 1; /* purecov: inspected */
685
1610
 
686
1611
bool check_duplicates_in_interval(const char *set_or_name,
687
1612
                                  const char *name, TYPELIB *typelib,
688
 
                                  const CHARSET_INFO * const cs, unsigned int *dup_val_count)
 
1613
                                  CHARSET_INFO *cs, unsigned int *dup_val_count)
689
1614
{
690
1615
  TYPELIB tmp= *typelib;
691
1616
  const char **cur_value= typelib->type_names;
726
1651
  RETURN VALUES
727
1652
    void
728
1653
*/
729
 
void calculate_interval_lengths(const CHARSET_INFO * const cs, TYPELIB *interval,
730
 
                                uint32_t *max_length, uint32_t *tot_length)
 
1654
void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
 
1655
                                uint32 *max_length, uint32 *tot_length)
731
1656
{
732
1657
  const char **pos;
733
 
  uint32_t *len;
 
1658
  uint *len;
734
1659
  *max_length= *tot_length= 0;
735
1660
  for (pos= interval->type_names, len= interval->type_lengths;
736
1661
       *pos ; pos++, len++)
737
1662
  {
738
 
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
 
1663
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
739
1664
    *tot_length+= length;
740
 
    set_if_bigger(*max_length, (uint32_t)length);
 
1665
    set_if_bigger(*max_length, (uint32)length);
741
1666
  }
742
1667
}
743
1668
 
762
1687
*/
763
1688
 
764
1689
int prepare_create_field(Create_field *sql_field, 
765
 
                         uint32_t *blob_columns,
 
1690
                         uint *blob_columns,
766
1691
                         int *timestamps, int *timestamps_with_niladic,
767
 
                         int64_t table_flags __attribute__((unused)))
 
1692
                         longlong table_flags __attribute__((__unused__)))
768
1693
{
769
1694
  unsigned int dup_val_count;
770
1695
 
775
1700
  assert(sql_field->charset);
776
1701
 
777
1702
  switch (sql_field->sql_type) {
778
 
  case DRIZZLE_TYPE_BLOB:
 
1703
  case MYSQL_TYPE_BLOB:
779
1704
    sql_field->pack_flag=FIELDFLAG_BLOB |
780
1705
      pack_length_to_packflag(sql_field->pack_length -
781
1706
                              portable_sizeof_char_ptr);
785
1710
    sql_field->unireg_check=Field::BLOB_FIELD;
786
1711
    (*blob_columns)++;
787
1712
    break;
788
 
  case DRIZZLE_TYPE_VARCHAR:
 
1713
  case MYSQL_TYPE_VARCHAR:
 
1714
  case MYSQL_TYPE_STRING:
789
1715
    sql_field->pack_flag=0;
790
1716
    if (sql_field->charset->state & MY_CS_BINSORT)
791
1717
      sql_field->pack_flag|=FIELDFLAG_BINARY;
792
1718
    break;
793
 
  case DRIZZLE_TYPE_ENUM:
 
1719
  case MYSQL_TYPE_ENUM:
794
1720
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
795
1721
      FIELDFLAG_INTERVAL;
796
1722
    if (sql_field->charset->state & MY_CS_BINSORT)
801
1727
                                     sql_field->charset, &dup_val_count))
802
1728
      return(1);
803
1729
    break;
804
 
  case DRIZZLE_TYPE_NEWDATE:  // Rest of string types
805
 
  case DRIZZLE_TYPE_TIME:
806
 
  case DRIZZLE_TYPE_DATETIME:
807
 
  case DRIZZLE_TYPE_NULL:
 
1730
  case MYSQL_TYPE_SET:
 
1731
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
 
1732
      FIELDFLAG_BITFIELD;
 
1733
    if (sql_field->charset->state & MY_CS_BINSORT)
 
1734
      sql_field->pack_flag|=FIELDFLAG_BINARY;
 
1735
    sql_field->unireg_check=Field::BIT_FIELD;
 
1736
    if (check_duplicates_in_interval("SET",sql_field->field_name,
 
1737
                                 sql_field->interval,
 
1738
                                     sql_field->charset, &dup_val_count))
 
1739
      return(1);
 
1740
    /* Check that count of unique members is not more then 64 */
 
1741
    if (sql_field->interval->count -  dup_val_count > sizeof(longlong)*8)
 
1742
    {
 
1743
       my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
 
1744
       return(1);
 
1745
    }
 
1746
    break;
 
1747
  case MYSQL_TYPE_NEWDATE:  // Rest of string types
 
1748
  case MYSQL_TYPE_TIME:
 
1749
  case MYSQL_TYPE_DATETIME:
 
1750
  case MYSQL_TYPE_NULL:
808
1751
    sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
809
1752
    break;
810
 
  case DRIZZLE_TYPE_NEWDECIMAL:
 
1753
  case MYSQL_TYPE_NEWDECIMAL:
811
1754
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
812
1755
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
813
1756
                           FIELDFLAG_DECIMAL) |
814
 
                          (sql_field->flags & DECIMAL_FLAG ?  FIELDFLAG_DECIMAL_POSITION : 0) |
 
1757
                          (sql_field->flags & ZEROFILL_FLAG ?
 
1758
                           FIELDFLAG_ZEROFILL : 0) |
815
1759
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
816
1760
    break;
817
 
  case DRIZZLE_TYPE_TIMESTAMP:
 
1761
  case MYSQL_TYPE_TIMESTAMP:
818
1762
    /* We should replace old TIMESTAMP fields with their newer analogs */
819
1763
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
820
1764
    {
835
1779
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
836
1780
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
837
1781
                           FIELDFLAG_DECIMAL) |
 
1782
                          (sql_field->flags & ZEROFILL_FLAG ?
 
1783
                           FIELDFLAG_ZEROFILL : 0) |
838
1784
                          f_settype((uint) sql_field->sql_type) |
839
1785
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
840
1786
    break;
841
1787
  }
842
 
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
843
 
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
 
1788
  if (!(sql_field->flags & NOT_NULL_FLAG))
844
1789
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
845
1790
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
846
1791
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
877
1822
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
878
1823
                           Alter_info *alter_info,
879
1824
                           bool tmp_table,
880
 
                               uint32_t *db_options,
 
1825
                               uint *db_options,
881
1826
                               handler *file, KEY **key_info_buffer,
882
 
                               uint32_t *key_count, int select_field_count)
 
1827
                               uint *key_count, int select_field_count)
883
1828
{
884
1829
  const char    *key_name;
885
1830
  Create_field  *sql_field,*dup_field;
892
1837
  int           select_field_pos,auto_increment=0;
893
1838
  List_iterator<Create_field> it(alter_info->create_list);
894
1839
  List_iterator<Create_field> it2(alter_info->create_list);
895
 
  uint32_t total_uneven_bit_length= 0;
 
1840
  uint total_uneven_bit_length= 0;
896
1841
 
897
1842
  select_field_pos= alter_info->create_list.elements - select_field_count;
898
1843
  null_fields=blob_columns=0;
901
1846
 
902
1847
  for (field_no=0; (sql_field=it++) ; field_no++)
903
1848
  {
904
 
    const CHARSET_INFO *save_cs;
 
1849
    CHARSET_INFO *save_cs;
905
1850
 
906
1851
    /*
907
1852
      Initialize length from its original value (number of characters),
912
1857
    if (!sql_field->charset)
913
1858
      sql_field->charset= create_info->default_table_charset;
914
1859
    /*
915
 
      table_charset is set in ALTER Table if we want change character set
 
1860
      table_charset is set in ALTER TABLE if we want change character set
916
1861
      for all varchar/char columns.
917
1862
      But the table charset must not affect the BLOB fields, so don't
918
1863
      allow to change my_charset_bin to somethig else.
938
1883
    */
939
1884
    if (sql_field->def && 
940
1885
        save_cs != sql_field->def->collation.collation &&
941
 
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
 
1886
        (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
 
1887
         sql_field->sql_type == MYSQL_TYPE_STRING ||
 
1888
         sql_field->sql_type == MYSQL_TYPE_SET ||
 
1889
         sql_field->sql_type == MYSQL_TYPE_ENUM))
942
1890
    {
943
1891
      /*
944
1892
        Starting from 5.1 we work here with a copy of Create_field
960
1908
      }
961
1909
    }
962
1910
 
963
 
    if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
 
1911
    if (sql_field->sql_type == MYSQL_TYPE_SET ||
 
1912
        sql_field->sql_type == MYSQL_TYPE_ENUM)
964
1913
    {
965
 
      uint32_t dummy;
966
 
      const CHARSET_INFO * const cs= sql_field->charset;
 
1914
      uint32 dummy;
 
1915
      CHARSET_INFO *cs= sql_field->charset;
967
1916
      TYPELIB *interval= sql_field->interval;
968
1917
 
969
1918
      /*
983
1932
        List_iterator<String> int_it(sql_field->interval_list);
984
1933
        String conv, *tmp;
985
1934
        char comma_buf[4];
986
 
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
987
 
                                          (unsigned char*) comma_buf + 
 
1935
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
 
1936
                                          (uchar*) comma_buf + 
988
1937
                                          sizeof(comma_buf));
989
1938
        assert(comma_length > 0);
990
 
        for (uint32_t i= 0; (tmp= int_it++); i++)
 
1939
        for (uint i= 0; (tmp= int_it++); i++)
991
1940
        {
992
 
          uint32_t lengthsp;
 
1941
          uint lengthsp;
993
1942
          if (String::needs_conversion(tmp->length(), tmp->charset(),
994
1943
                                       cs, &dummy))
995
1944
          {
996
 
            uint32_t cnv_errs;
 
1945
            uint cnv_errs;
997
1946
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
998
1947
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
999
1948
                                                  conv.length());
1004
1953
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
1005
1954
                                       interval->type_lengths[i]);
1006
1955
          interval->type_lengths[i]= lengthsp;
1007
 
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
 
1956
          ((uchar *)interval->type_names[i])[lengthsp]= '\0';
 
1957
          if (sql_field->sql_type == MYSQL_TYPE_SET)
 
1958
          {
 
1959
            if (cs->coll->instr(cs, interval->type_names[i], 
 
1960
                                interval->type_lengths[i], 
 
1961
                                comma_buf, comma_length, NULL, 0))
 
1962
            {
 
1963
              my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
 
1964
              return(true);
 
1965
            }
 
1966
          }
1008
1967
        }
1009
1968
        sql_field->interval_list.empty(); // Don't need interval_list anymore
1010
1969
      }
1011
1970
 
1012
 
      /* DRIZZLE_TYPE_ENUM */
1013
 
      {
1014
 
        uint32_t field_length;
1015
 
        assert(sql_field->sql_type == DRIZZLE_TYPE_ENUM);
 
1971
      if (sql_field->sql_type == MYSQL_TYPE_SET)
 
1972
      {
 
1973
        uint32 field_length;
 
1974
        if (sql_field->def != NULL)
 
1975
        {
 
1976
          char *not_used;
 
1977
          uint not_used2;
 
1978
          bool not_found= 0;
 
1979
          String str, *def= sql_field->def->val_str(&str);
 
1980
          if (def == NULL) /* SQL "NULL" maps to NULL */
 
1981
          {
 
1982
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
 
1983
            {
 
1984
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
 
1985
              return(true);
 
1986
            }
 
1987
 
 
1988
            /* else, NULL is an allowed value */
 
1989
            (void) find_set(interval, NULL, 0,
 
1990
                            cs, &not_used, &not_used2, &not_found);
 
1991
          }
 
1992
          else /* not NULL */
 
1993
          {
 
1994
            (void) find_set(interval, def->ptr(), def->length(),
 
1995
                            cs, &not_used, &not_used2, &not_found);
 
1996
          }
 
1997
 
 
1998
          if (not_found)
 
1999
          {
 
2000
            my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
 
2001
            return(true);
 
2002
          }
 
2003
        }
 
2004
        calculate_interval_lengths(cs, interval, &dummy, &field_length);
 
2005
        sql_field->length= field_length + (interval->count - 1);
 
2006
      }
 
2007
      else  /* MYSQL_TYPE_ENUM */
 
2008
      {
 
2009
        uint32 field_length;
 
2010
        assert(sql_field->sql_type == MYSQL_TYPE_ENUM);
1016
2011
        if (sql_field->def != NULL)
1017
2012
        {
1018
2013
          String str, *def= sql_field->def->val_str(&str);
1094
2089
            null_fields--;
1095
2090
          sql_field->flags=             dup_field->flags;
1096
2091
          sql_field->interval=          dup_field->interval;
1097
 
          sql_field->vcol_info=         dup_field->vcol_info;
1098
 
          sql_field->is_stored=      dup_field->is_stored;
1099
2092
          it2.remove();                 // Remove first (create) definition
1100
2093
          select_field_pos--;
1101
2094
          break;
1104
2097
    }
1105
2098
    /* Don't pack rows in old tables if the user has requested this */
1106
2099
    if ((sql_field->flags & BLOB_FLAG) ||
1107
 
        (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
2100
        (sql_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
1108
2101
      (*db_options)|= HA_OPTION_PACK_RECORD;
1109
2102
    it2.rewind();
1110
2103
  }
1122
2115
                             &timestamps, &timestamps_with_niladic,
1123
2116
                             file->ha_table_flags()))
1124
2117
      return(true);
1125
 
    if (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
 
2118
    if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
1126
2119
      create_info->varchar= true;
1127
2120
    sql_field->offset= record_offset;
1128
2121
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1129
2122
      auto_increment++;
1130
 
    /*
1131
 
          For now skip fields that are not physically stored in the database
1132
 
          (virtual fields) and update their offset later 
1133
 
          (see the next loop).
1134
 
        */
1135
 
    if (sql_field->is_stored)
1136
 
      record_offset+= sql_field->pack_length;
1137
 
  }
1138
 
  /* Update virtual fields' offset */
1139
 
  it.rewind();
1140
 
  while ((sql_field=it++))
1141
 
  {
1142
 
    if (not sql_field->is_stored)
1143
 
    {
1144
 
      sql_field->offset= record_offset;
1145
 
      record_offset+= sql_field->pack_length;
1146
 
    }
 
2123
    record_offset+= sql_field->pack_length;
1147
2124
  }
1148
2125
  if (timestamps_with_niladic > 1)
1149
2126
  {
1175
2152
 
1176
2153
  List_iterator<Key> key_iterator(alter_info->key_list);
1177
2154
  List_iterator<Key> key_iterator2(alter_info->key_list);
1178
 
  uint32_t key_parts=0, fk_key_count=0;
 
2155
  uint key_parts=0, fk_key_count=0;
1179
2156
  bool primary_key=0,unique_key=0;
1180
2157
  Key *key, *key2;
1181
 
  uint32_t tmp, key_number;
 
2158
  uint tmp, key_number;
1182
2159
  /* special marker for keys to be ignored */
1183
2160
  static char ignore_key[1];
1184
2161
 
1190
2167
    if (key->type == Key::FOREIGN_KEY)
1191
2168
    {
1192
2169
      fk_key_count++;
1193
 
      if (((Foreign_key *)key)->validate(alter_info->create_list))
1194
 
        return true;
1195
2170
      Foreign_key *fk_key= (Foreign_key*) key;
1196
2171
      if (fk_key->ref_columns.elements &&
1197
2172
          fk_key->ref_columns.elements != fk_key->columns.elements)
1270
2245
  key_number=0;
1271
2246
  for (; (key=key_iterator++) ; key_number++)
1272
2247
  {
1273
 
    uint32_t key_length=0;
 
2248
    uint key_length=0;
1274
2249
    Key_part_spec *column;
1275
2250
 
1276
2251
    if (key->name.str == ignore_key)
1297
2272
    if (key->generated)
1298
2273
      key_info->flags|= HA_GENERATED_KEY;
1299
2274
 
1300
 
    key_info->key_parts=(uint8_t) key->columns.elements;
 
2275
    key_info->key_parts=(uint8) key->columns.elements;
1301
2276
    key_info->key_part=key_part_info;
1302
2277
    key_info->usable_key_parts= key_number;
1303
2278
    key_info->algorithm= key->key_create_info.algorithm;
1314
2289
    if (key_info->block_size)
1315
2290
      key_info->flags|= HA_USES_BLOCK_SIZE;
1316
2291
 
1317
 
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
2292
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
1318
2293
                                           key->key_create_info.comment.str,
1319
2294
                                           key->key_create_info.comment.str +
1320
2295
                                           key->key_create_info.comment.length,
1336
2311
    }
1337
2312
 
1338
2313
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
1339
 
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
 
2314
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
1340
2315
    {
1341
 
      uint32_t length;
 
2316
      uint length;
1342
2317
      Key_part_spec *dup_column;
1343
2318
 
1344
2319
      it.rewind();
1381
2356
            return(true);
1382
2357
          }
1383
2358
        }
1384
 
        if (not sql_field->is_stored)
1385
 
        {
1386
 
          /* Key fields must always be physically stored. */
1387
 
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
1388
 
          return(true);
1389
 
        }
1390
 
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
1391
 
        {
1392
 
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
1393
 
          return(true);
1394
 
        }
1395
2359
        if (!(sql_field->flags & NOT_NULL_FLAG))
1396
2360
        {
1397
2361
          if (key->type == Key::PRIMARY)
1419
2383
      }
1420
2384
 
1421
2385
      key_part_info->fieldnr= field;
1422
 
      key_part_info->offset=  (uint16_t) sql_field->offset;
 
2386
      key_part_info->offset=  (uint16) sql_field->offset;
1423
2387
      key_part_info->key_type=sql_field->pack_flag;
1424
2388
      length= sql_field->key_length;
1425
2389
 
1430
2394
          if ((length=column->length) > max_key_length ||
1431
2395
              length > file->max_key_part_length())
1432
2396
          {
1433
 
            length=cmin(max_key_length, file->max_key_part_length());
 
2397
            length=min(max_key_length, file->max_key_part_length());
1434
2398
            if (key->type == Key::MULTIPLE)
1435
2399
            {
1436
2400
              /* not a critical problem */
1437
 
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
2401
              char warn_buff[MYSQL_ERRMSG_SIZE];
1438
2402
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1439
2403
                       length);
1440
 
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2404
              push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1441
2405
                           ER_TOO_LONG_KEY, warn_buff);
1442
2406
              /* Align key length to multibyte char boundary */
1443
2407
              length-= length % sql_field->charset->mbmaxlen;
1473
2437
        if (key->type == Key::MULTIPLE)
1474
2438
        {
1475
2439
          /* not a critical problem */
1476
 
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
2440
          char warn_buff[MYSQL_ERRMSG_SIZE];
1477
2441
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1478
2442
                   length);
1479
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2443
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1480
2444
                       ER_TOO_LONG_KEY, warn_buff);
1481
2445
          /* Align key length to multibyte char boundary */
1482
2446
          length-= length % sql_field->charset->mbmaxlen;
1487
2451
          return(true);
1488
2452
        }
1489
2453
      }
1490
 
      key_part_info->length=(uint16_t) length;
 
2454
      key_part_info->length=(uint16) length;
1491
2455
      /* Use packed keys for long strings on the first column */
1492
2456
      if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
1493
2457
          (length >= KEY_DEFAULT_PACK_LENGTH &&
1494
 
           (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
 
2458
           (sql_field->sql_type == MYSQL_TYPE_STRING ||
 
2459
            sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
1495
2460
            sql_field->pack_flag & FIELDFLAG_BLOB)))
1496
2461
      {
1497
2462
        if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
1498
 
            sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
 
2463
            sql_field->sql_type == MYSQL_TYPE_VARCHAR)
1499
2464
          key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
1500
2465
        else
1501
2466
          key_info->flags|= HA_PACK_KEY;
1539
2504
    }
1540
2505
    if (!(key_info->flags & HA_NULL_PART_KEY))
1541
2506
      unique_key=1;
1542
 
    key_info->key_length=(uint16_t) key_length;
 
2507
    key_info->key_length=(uint16) key_length;
1543
2508
    if (key_length > max_key_length)
1544
2509
    {
1545
2510
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1559
2524
    return(true);
1560
2525
  }
1561
2526
  /* Sort keys in optimized order */
1562
 
  my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
 
2527
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
1563
2528
           (qsort_cmp) sort_keys);
1564
2529
  create_info->null_bits= null_fields;
1565
2530
 
1571
2536
 
1572
2537
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
1573
2538
        !sql_field->def &&
1574
 
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
 
2539
        sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
1575
2540
        (sql_field->flags & NOT_NULL_FLAG) &&
1576
2541
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1577
2542
    {
1643
2608
        In this case the error is given
1644
2609
*/
1645
2610
 
1646
 
static bool prepare_blob_field(THD *thd __attribute__((unused)),
 
2611
static bool prepare_blob_field(THD *thd __attribute__((__unused__)),
1647
2612
                               Create_field *sql_field)
1648
2613
{
1649
2614
 
1657
2622
    
1658
2623
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1659
2624
  {
1660
 
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
 
2625
    if (sql_field->sql_type == MYSQL_TYPE_BLOB)
1661
2626
    {
1662
2627
      /* The user has given a length to the blob column */
1663
2628
      sql_field->sql_type= get_blob_type_from_length(sql_field->length);
1686
2651
 
1687
2652
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
1688
2653
{
1689
 
  if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
 
2654
  if (sql_field->sql_type == MYSQL_TYPE_SET ||
 
2655
      sql_field->sql_type == MYSQL_TYPE_ENUM)
1690
2656
  {
1691
 
    uint32_t field_length, dummy;
1692
 
    /* DRIZZLE_TYPE_ENUM */
 
2657
    uint32 field_length, dummy;
 
2658
    if (sql_field->sql_type == MYSQL_TYPE_SET)
 
2659
    {
 
2660
      calculate_interval_lengths(sql_field->charset,
 
2661
                                 sql_field->interval, &dummy, 
 
2662
                                 &field_length);
 
2663
      sql_field->length= field_length + 
 
2664
                         (sql_field->interval->count - 1);
 
2665
    }
 
2666
    else /* MYSQL_TYPE_ENUM */
1693
2667
    {
1694
2668
      calculate_interval_lengths(sql_field->charset,
1695
2669
                                 sql_field->interval,
1718
2692
    fields              List of fields to create
1719
2693
    keys                List of keys to create
1720
2694
    internal_tmp_table  Set to 1 if this is an internal temporary table
1721
 
                        (From ALTER Table)
 
2695
                        (From ALTER TABLE)
1722
2696
    select_field_count  
1723
2697
 
1724
2698
  DESCRIPTION
1744
2718
                                HA_CREATE_INFO *create_info,
1745
2719
                                Alter_info *alter_info,
1746
2720
                                bool internal_tmp_table,
1747
 
                                uint32_t select_field_count,
1748
 
                                bool lock_open_lock)
 
2721
                                uint select_field_count)
1749
2722
{
1750
2723
  char          path[FN_REFLEN];
1751
 
  uint32_t          path_length;
 
2724
  uint          path_length;
1752
2725
  const char    *alias;
1753
2726
  uint          db_options, key_count;
1754
2727
  KEY           *key_info_buffer;
1810
2783
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1811
2784
    {
1812
2785
      create_info->table_existed= 1;            // Mark that table existed
1813
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2786
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1814
2787
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1815
2788
                          alias);
1816
2789
      error= 0;
1820
2793
    goto err;
1821
2794
  }
1822
2795
 
1823
 
  if (lock_open_lock)
1824
 
    pthread_mutex_lock(&LOCK_open);
 
2796
  VOID(pthread_mutex_lock(&LOCK_open));
1825
2797
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1826
2798
  {
1827
2799
    if (!access(path,F_OK))
1878
2850
    }
1879
2851
  }
1880
2852
 
1881
 
  thd->set_proc_info("creating table");
 
2853
  thd_proc_info(thd, "creating table");
1882
2854
  create_info->table_existed= 0;                // Mark that table is created
1883
2855
 
1884
2856
#ifdef HAVE_READLINK
1897
2869
#endif /* HAVE_READLINK */
1898
2870
  {
1899
2871
    if (create_info->data_file_name)
1900
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
2872
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
1901
2873
                   "DATA DIRECTORY option ignored");
1902
2874
    if (create_info->index_file_name)
1903
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
2875
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
1904
2876
                   "INDEX DIRECTORY option ignored");
1905
2877
    create_info->data_file_name= create_info->index_file_name= 0;
1906
2878
  }
1937
2909
    write_bin_log(thd, true, thd->query, thd->query_length);
1938
2910
  error= false;
1939
2911
unlock_and_end:
1940
 
  if (lock_open_lock)
1941
 
    pthread_mutex_unlock(&LOCK_open);
 
2912
  VOID(pthread_mutex_unlock(&LOCK_open));
1942
2913
 
1943
2914
err:
1944
 
  thd->set_proc_info("After create");
 
2915
  thd_proc_info(thd, "After create");
1945
2916
  delete file;
1946
2917
  return(error);
1947
2918
 
1948
2919
warn:
1949
2920
  error= false;
1950
 
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2921
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1951
2922
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1952
2923
                      alias);
1953
2924
  create_info->table_existed= 1;                // Mark that table existed
1963
2934
                        HA_CREATE_INFO *create_info,
1964
2935
                        Alter_info *alter_info,
1965
2936
                        bool internal_tmp_table,
1966
 
                        uint32_t select_field_count)
 
2937
                        uint select_field_count)
1967
2938
{
1968
 
  Table *name_lock= 0;
 
2939
  TABLE *name_lock= 0;
1969
2940
  bool result;
1970
2941
 
1971
2942
  /* Wait for any database locks */
1972
2943
  pthread_mutex_lock(&LOCK_lock_db);
1973
2944
  while (!thd->killed &&
1974
 
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
 
2945
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
1975
2946
  {
1976
2947
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1977
2948
    pthread_mutex_lock(&LOCK_lock_db);
1996
2967
    {
1997
2968
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1998
2969
      {
1999
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2970
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
2000
2971
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
2001
2972
                            table_name);
2002
2973
        create_info->table_existed= 1;
2014
2985
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
2015
2986
                                     alter_info,
2016
2987
                                     internal_tmp_table,
2017
 
                                     select_field_count, true);
 
2988
                                     select_field_count);
2018
2989
 
2019
2990
unlock:
2020
2991
  if (name_lock)
2059
3030
    Only 3 chars + '\0' left, so need to limit to 2 digit
2060
3031
    This is ok as we can't have more than 100 keys anyway
2061
3032
  */
2062
 
  for (uint32_t i=2 ; i< 100; i++)
 
3033
  for (uint i=2 ; i< 100; i++)
2063
3034
  {
2064
3035
    *buff_end= '_';
2065
3036
    int10_to_str(i, buff_end+1, 10);
2099
3070
bool
2100
3071
mysql_rename_table(handlerton *base, const char *old_db,
2101
3072
                   const char *old_name, const char *new_db,
2102
 
                   const char *new_name, uint32_t flags)
 
3073
                   const char *new_name, uint flags)
2103
3074
{
2104
3075
  THD *thd= current_thd;
2105
3076
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2124
3095
  if (lower_case_table_names == 2 && file &&
2125
3096
      !(file->ha_table_flags() & HA_FILE_BASED))
2126
3097
  {
2127
 
    my_stpcpy(tmp_name, old_name);
 
3098
    strmov(tmp_name, old_name);
2128
3099
    my_casedn_str(files_charset_info, tmp_name);
2129
3100
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2130
3101
                         flags & FN_FROM_IS_TMP);
2131
3102
    from_base= lc_from;
2132
3103
 
2133
 
    my_stpcpy(tmp_name, new_name);
 
3104
    strmov(tmp_name, new_name);
2134
3105
    my_casedn_str(files_charset_info, tmp_name);
2135
3106
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2136
3107
                         flags & FN_TO_IS_TMP);
2148
3119
  }
2149
3120
  delete file;
2150
3121
  if (error == HA_ERR_WRONG_COMMAND)
2151
 
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
 
3122
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
2152
3123
  else if (error)
2153
3124
    my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
2154
3125
  return(error != 0);
2174
3145
    Win32 clients must also have a WRITE LOCK on the table !
2175
3146
*/
2176
3147
 
2177
 
void wait_while_table_is_used(THD *thd, Table *table,
 
3148
void wait_while_table_is_used(THD *thd, TABLE *table,
2178
3149
                              enum ha_extra_function function)
2179
3150
{
2180
3151
 
2181
3152
  safe_mutex_assert_owner(&LOCK_open);
2182
3153
 
2183
 
  table->file->extra(function);
 
3154
  VOID(table->file->extra(function));
2184
3155
  /* Mark all tables that are in use as 'old' */
2185
3156
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
2186
3157
 
2208
3179
    Win32 clients must also have a WRITE LOCK on the table !
2209
3180
*/
2210
3181
 
2211
 
void close_cached_table(THD *thd, Table *table)
 
3182
void close_cached_table(THD *thd, TABLE *table)
2212
3183
{
2213
3184
 
2214
3185
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
2226
3197
  return;
2227
3198
}
2228
3199
 
2229
 
static int send_check_errmsg(THD *thd, TableList* table,
 
3200
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
2230
3201
                             const char* operator_name, const char* errmsg)
2231
3202
 
2232
3203
{
2243
3214
}
2244
3215
 
2245
3216
 
2246
 
static int prepare_for_repair(THD *thd, TableList *table_list,
 
3217
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
2247
3218
                              HA_CHECK_OPT *check_opt)
2248
3219
{
2249
3220
  int error= 0;
2250
 
  Table tmp_table, *table;
 
3221
  TABLE tmp_table, *table;
2251
3222
  TABLE_SHARE *share;
2252
3223
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
2253
3224
  const char **ext;
2259
3230
  if (!(table= table_list->table))              /* if open_ltable failed */
2260
3231
  {
2261
3232
    char key[MAX_DBKEY_LENGTH];
2262
 
    uint32_t key_length;
 
3233
    uint key_length;
2263
3234
 
2264
3235
    key_length= create_table_def_key(thd, key, table_list, 0);
2265
3236
    pthread_mutex_lock(&LOCK_open);
2281
3252
  }
2282
3253
 
2283
3254
  /*
2284
 
    REPAIR Table ... USE_FRM for temporary tables makes little sense.
 
3255
    REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
2285
3256
  */
2286
3257
  if (table->s->tmp_table)
2287
3258
  {
2311
3282
    goto end;                                   // No data file
2312
3283
 
2313
3284
  // Name of data file
2314
 
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
 
3285
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
2315
3286
  if (stat(from, &stat_info))
2316
3287
    goto end;                           // Can't use USE_FRM flag
2317
3288
 
2391
3362
    true  Message should be sent by caller 
2392
3363
          (admin operation or network communication failed)
2393
3364
*/
2394
 
static bool mysql_admin_table(THD* thd, TableList* tables,
 
3365
static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
2395
3366
                              HA_CHECK_OPT* check_opt,
2396
3367
                              const char *operator_name,
2397
3368
                              thr_lock_type lock_type,
2398
3369
                              bool open_for_modify,
2399
3370
                              bool no_warnings_for_error,
2400
 
                              uint32_t extra_open_options,
2401
 
                              int (*prepare_func)(THD *, TableList *,
 
3371
                              uint extra_open_options,
 
3372
                              int (*prepare_func)(THD *, TABLE_LIST *,
2402
3373
                                                  HA_CHECK_OPT *),
2403
3374
                              int (handler::*operator_func)(THD *,
2404
3375
                                                            HA_CHECK_OPT *))
2405
3376
{
2406
 
  TableList *table;
 
3377
  TABLE_LIST *table;
2407
3378
  SELECT_LEX *select= &thd->lex->select_lex;
2408
3379
  List<Item> field_list;
2409
3380
  Item *item;
2410
3381
  Protocol *protocol= thd->protocol;
2411
3382
  LEX *lex= thd->lex;
2412
3383
  int result_code= 0;
2413
 
  const CHARSET_INFO * const cs= system_charset_info;
 
3384
  CHARSET_INFO *cs= system_charset_info;
2414
3385
 
2415
3386
  if (end_active_trans(thd))
2416
3387
    return(1);
2436
3407
    char* db = table->db;
2437
3408
    bool fatal_error=0;
2438
3409
 
2439
 
    strxmov(table_name, db, ".", table->table_name, NULL);
 
3410
    strxmov(table_name, db, ".", table->table_name, NullS);
2440
3411
    thd->open_options|= extra_open_options;
2441
3412
    table->lock_type= lock_type;
2442
3413
    /* open only one table from local list of command */
2443
3414
    {
2444
 
      TableList *save_next_global, *save_next_local;
 
3415
      TABLE_LIST *save_next_global, *save_next_local;
2445
3416
      save_next_global= table->next_global;
2446
3417
      table->next_global= 0;
2447
3418
      save_next_local= table->next_local;
2448
3419
      table->next_local= 0;
2449
 
      select->table_list.first= (unsigned char*)table;
 
3420
      select->table_list.first= (uchar*)table;
2450
3421
      /*
2451
3422
        Time zone tables and SP tables can be add to lex->query_tables list,
2452
3423
        so it have to be prepared.
2457
3428
      lex->query_tables_last= &table->next_global;
2458
3429
      lex->query_tables_own_last= 0;
2459
3430
      thd->no_warnings_for_error= no_warnings_for_error;
 
3431
      table->required_type=FRMTYPE_TABLE;
2460
3432
 
2461
3433
      open_and_lock_tables(thd, table);
2462
3434
      thd->no_warnings_for_error= 0;
2483
3455
    }
2484
3456
 
2485
3457
    /*
2486
 
      CHECK Table command is only command where VIEW allowed here and this
 
3458
      CHECK TABLE command is only command where VIEW allowed here and this
2487
3459
      command use only temporary teble method for VIEWs resolving => there
2488
3460
      can't be VIEW tree substitition of join view => if opening table
2489
 
      succeed then table->table will have real Table pointer as value (in
 
3461
      succeed then table->table will have real TABLE pointer as value (in
2490
3462
      case of join view substitution table->table can be 0, but here it is
2491
3463
      impossible)
2492
3464
    */
2493
3465
    if (!table->table)
2494
3466
    {
2495
3467
      if (!thd->warn_list.elements)
2496
 
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
3468
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
2497
3469
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2498
3470
      goto send_result;
2499
3471
    }
2501
3473
    if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
2502
3474
    {
2503
3475
      /* purecov: begin inspected */
2504
 
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
2505
 
      uint32_t length;
 
3476
      char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
 
3477
      uint length;
2506
3478
      protocol->prepare_for_resend();
2507
3479
      protocol->store(table_name, system_charset_info);
2508
3480
      protocol->store(operator_name, system_charset_info);
2533
3505
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2534
3506
                              RTFC_CHECK_KILLED_FLAG);
2535
3507
      thd->exit_cond(old_message);
 
3508
      DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
2536
3509
      if (thd->killed)
2537
3510
        goto err;
2538
3511
      open_for_modify= 0;
2583
3556
    lex->cleanup_after_one_table_open();
2584
3557
    thd->clear_error();  // these errors shouldn't get client
2585
3558
    {
2586
 
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
2587
 
      DRIZZLE_ERROR *err;
 
3559
      List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
 
3560
      MYSQL_ERROR *err;
2588
3561
      while ((err= it++))
2589
3562
      {
2590
3563
        protocol->prepare_for_resend();
2597
3570
        if (protocol->write())
2598
3571
          goto err;
2599
3572
      }
2600
 
      drizzle_reset_errors(thd, true);
 
3573
      mysql_reset_errors(thd, true);
2601
3574
    }
2602
3575
    protocol->prepare_for_resend();
2603
3576
    protocol->store(table_name, system_charset_info);
2609
3582
    case HA_ADMIN_NOT_IMPLEMENTED:
2610
3583
      {
2611
3584
        char buf[ERRMSGSIZE+20];
2612
 
        uint32_t length=snprintf(buf, ERRMSGSIZE,
 
3585
        uint length=snprintf(buf, ERRMSGSIZE,
2613
3586
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
2614
3587
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2615
3588
        protocol->store(buf, length, system_charset_info);
2619
3592
    case HA_ADMIN_NOT_BASE_TABLE:
2620
3593
      {
2621
3594
        char buf[ERRMSGSIZE+20];
2622
 
        uint32_t length= snprintf(buf, ERRMSGSIZE,
 
3595
        uint length= snprintf(buf, ERRMSGSIZE,
2623
3596
                              ER(ER_BAD_TABLE_ERROR), table_name);
2624
3597
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2625
3598
        protocol->store(buf, length, system_charset_info);
2666
3639
    {
2667
3640
      /*
2668
3641
        This is currently used only by InnoDB. ha_innobase::optimize() answers
2669
 
        "try with alter", so here we close the table, do an ALTER Table,
 
3642
        "try with alter", so here we close the table, do an ALTER TABLE,
2670
3643
        reopen the table and do ha_innobase::analyze() on it.
2671
3644
      */
2672
3645
      ha_autocommit_or_rollback(thd, 0);
2673
3646
      close_thread_tables(thd);
2674
 
      TableList *save_next_local= table->next_local,
 
3647
      TABLE_LIST *save_next_local= table->next_local,
2675
3648
                 *save_next_global= table->next_global;
2676
3649
      table->next_local= table->next_global= 0;
2677
3650
      tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2734
3707
    case HA_ADMIN_NEEDS_ALTER:
2735
3708
    {
2736
3709
      char buf[ERRMSGSIZE];
2737
 
      uint32_t length;
 
3710
      uint length;
2738
3711
 
2739
3712
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2740
3713
      length=snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
2746
3719
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
2747
3720
      {
2748
3721
        char buf[ERRMSGSIZE+20];
2749
 
        uint32_t length=snprintf(buf, ERRMSGSIZE,
2750
 
                             _("Unknown - internal error %d during operation"),
 
3722
        uint length=snprintf(buf, ERRMSGSIZE,
 
3723
                             "Unknown - internal error %d during operation",
2751
3724
                             result_code);
2752
3725
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2753
3726
        protocol->store(buf, length, system_charset_info);
2793
3766
}
2794
3767
 
2795
3768
 
2796
 
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3769
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
2797
3770
{
2798
3771
  return(mysql_admin_table(thd, tables, check_opt,
2799
3772
                                "repair", TL_WRITE, 1,
2804
3777
}
2805
3778
 
2806
3779
 
2807
 
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3780
bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
2808
3781
{
2809
3782
  return(mysql_admin_table(thd, tables, check_opt,
2810
3783
                                "optimize", TL_WRITE, 1,0,0,0,
2825
3798
   true  error
2826
3799
*/
2827
3800
 
2828
 
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
 
3801
bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
2829
3802
                             LEX_STRING *key_cache_name)
2830
3803
{
2831
3804
  HA_CHECK_OPT check_opt;
2872
3845
    0     ok
2873
3846
*/
2874
3847
 
2875
 
int reassign_keycache_tables(THD *thd __attribute__((unused)),
 
3848
int reassign_keycache_tables(THD *thd __attribute__((__unused__)),
2876
3849
                             KEY_CACHE *src_cache,
2877
3850
                             KEY_CACHE *dst_cache)
2878
3851
{
2896
3869
    @retval       0                        success
2897
3870
    @retval       1                        error
2898
3871
*/
2899
 
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
 
3872
bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
2900
3873
                                  char *dst_path, HA_CREATE_INFO *create_info)
2901
3874
{
2902
3875
  HA_CREATE_INFO local_create_info;
2903
3876
  Alter_info alter_info;
2904
3877
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
2905
 
  uint32_t keys= schema_table->table->s->keys;
2906
 
  uint32_t db_options= 0;
 
3878
  uint keys= schema_table->table->s->keys;
 
3879
  uint db_options= 0;
2907
3880
 
2908
 
  memset(&local_create_info, 0, sizeof(local_create_info));
 
3881
  bzero((char*) &local_create_info, sizeof(local_create_info));
2909
3882
  local_create_info.db_type= schema_table->table->s->db_type();
2910
3883
  local_create_info.row_type= schema_table->table->s->row_type;
2911
3884
  local_create_info.default_table_charset=default_charset_info;
2920
3893
                                 &schema_table->table->s->key_info, &keys, 0))
2921
3894
    return(1);
2922
3895
  local_create_info.max_rows= 0;
2923
 
  if (mysql_create_frm(thd, dst_path, NULL, NULL,
 
3896
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
2924
3897
                       &local_create_info, alter_info.create_list,
2925
3898
                       keys, schema_table->table->s->key_info,
2926
3899
                       schema_table->table->file))
2944
3917
    true  error
2945
3918
*/
2946
3919
 
2947
 
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
 
3920
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
2948
3921
                             HA_CREATE_INFO *create_info)
2949
3922
{
2950
 
  Table *name_lock= 0;
 
3923
  TABLE *name_lock= 0;
2951
3924
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
2952
 
  uint32_t dst_path_length;
 
3925
  uint dst_path_length;
2953
3926
  char *db= table->db;
2954
3927
  char *table_name= table->table_name;
2955
3928
  int  err;
2956
3929
  bool res= true;
2957
 
  uint32_t not_used;
 
3930
  uint not_used;
 
3931
 
 
3932
 
 
3933
  /* CREATE TABLE ... LIKE is not allowed for views. */
 
3934
  src_table->required_type= FRMTYPE_TABLE;
2958
3935
 
2959
3936
  /*
2960
3937
    By opening source table we guarantee that it exists and no concurrent
2968
3945
  if (open_tables(thd, &src_table, &not_used, 0))
2969
3946
    return(true);
2970
3947
 
2971
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
 
3948
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
 
3949
 
 
3950
  DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
2972
3951
 
2973
3952
  /* 
2974
3953
    Check that destination tables does not exist. Note that its name
2993
3972
      goto table_exists;
2994
3973
  }
2995
3974
 
 
3975
  DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
 
3976
 
2996
3977
  /*
2997
3978
    Create a new table by copying from source table
2998
3979
 
3006
3987
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
3007
3988
    during the call to ha_create_table(). See bug #28614 for more info.
3008
3989
  */
3009
 
  pthread_mutex_lock(&LOCK_open);
 
3990
  VOID(pthread_mutex_lock(&LOCK_open));
3010
3991
  if (src_table->schema_table)
3011
3992
  {
3012
3993
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
3013
3994
    {
3014
 
      pthread_mutex_unlock(&LOCK_open);
 
3995
      VOID(pthread_mutex_unlock(&LOCK_open));
3015
3996
      goto err;
3016
3997
    }
3017
3998
  }
3021
4002
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
3022
4003
    else
3023
4004
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
3024
 
    pthread_mutex_unlock(&LOCK_open);
 
4005
    VOID(pthread_mutex_unlock(&LOCK_open));
3025
4006
    goto err;
3026
4007
  }
3027
4008
 
3030
4011
    creation, instead create the table directly (for both normal
3031
4012
    and temporary tables).
3032
4013
  */
 
4014
  DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
 
4015
 
3033
4016
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
3034
4017
  if (thd->variables.keep_files_on_create)
3035
4018
    create_info->options|= HA_CREATE_KEEP_FILES;
3036
4019
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
3037
 
  pthread_mutex_unlock(&LOCK_open);
 
4020
  VOID(pthread_mutex_unlock(&LOCK_open));
3038
4021
 
3039
4022
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3040
4023
  {
3053
4036
    goto err;       /* purecov: inspected */
3054
4037
  }
3055
4038
 
 
4039
  DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
 
4040
 
3056
4041
  /*
3057
4042
    We have to write the query before we unlock the tables.
3058
4043
  */
3089
4074
          of this function.
3090
4075
        */
3091
4076
        table->table= name_lock;
3092
 
        pthread_mutex_lock(&LOCK_open);
 
4077
        VOID(pthread_mutex_lock(&LOCK_open));
3093
4078
        if (reopen_name_locked_table(thd, table, false))
3094
4079
        {
3095
 
          pthread_mutex_unlock(&LOCK_open);
 
4080
          VOID(pthread_mutex_unlock(&LOCK_open));
3096
4081
          goto err;
3097
4082
        }
3098
 
        pthread_mutex_unlock(&LOCK_open);
 
4083
        VOID(pthread_mutex_unlock(&LOCK_open));
3099
4084
 
3100
4085
        int result= store_create_info(thd, table, &query,
3101
4086
                                               create_info);
3119
4104
table_exists:
3120
4105
  if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
3121
4106
  {
3122
 
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
4107
    char warn_buff[MYSQL_ERRMSG_SIZE];
3123
4108
    snprintf(warn_buff, sizeof(warn_buff),
3124
4109
             ER(ER_TABLE_EXISTS_ERROR), table_name);
3125
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4110
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3126
4111
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3127
4112
    res= false;
3128
4113
  }
3140
4125
}
3141
4126
 
3142
4127
 
3143
 
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
4128
bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
3144
4129
{
3145
4130
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3146
4131
 
3150
4135
}
3151
4136
 
3152
4137
 
3153
 
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
 
4138
bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
3154
4139
{
3155
4140
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3156
4141
 
3164
4149
/* table_list should contain just one table */
3165
4150
static int
3166
4151
mysql_discard_or_import_tablespace(THD *thd,
3167
 
                                   TableList *table_list,
 
4152
                                   TABLE_LIST *table_list,
3168
4153
                                   enum tablespace_op_type tablespace_op)
3169
4154
{
3170
 
  Table *table;
3171
 
  bool discard;
 
4155
  TABLE *table;
 
4156
  my_bool discard;
3172
4157
  int error;
3173
4158
 
3174
4159
  /*
3175
4160
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
3176
 
    ALTER Table
 
4161
    ALTER TABLE
3177
4162
  */
3178
4163
 
3179
 
  thd->set_proc_info("discard_or_import_tablespace");
 
4164
  thd_proc_info(thd, "discard_or_import_tablespace");
3180
4165
 
3181
4166
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3182
4167
 
3193
4178
 
3194
4179
  error= table->file->ha_discard_or_import_tablespace(discard);
3195
4180
 
3196
 
  thd->set_proc_info("end");
 
4181
  thd_proc_info(thd, "end");
3197
4182
 
3198
4183
  if (error)
3199
4184
    goto err;
3200
4185
 
3201
 
  /* The ALTER Table is always in its own transaction */
 
4186
  /* The ALTER TABLE is always in its own transaction */
3202
4187
  error = ha_autocommit_or_rollback(thd, 0);
3203
4188
  if (end_active_trans(thd))
3204
4189
    error=1;
3227
4212
 
3228
4213
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
3229
4214
{
3230
 
  uint32_t flags= alter_info->flags;
 
4215
  uint flags= alter_info->flags;
3231
4216
 
3232
4217
  if (ALTER_ADD_COLUMN & flags)
3233
4218
    *alter_flags|= HA_ADD_COLUMN;
3272
4257
   table has in arguments create_list, key_list and create_info.
3273
4258
 
3274
4259
   By comparing the changes between the original and new table
3275
 
   we can determine how much it has changed after ALTER Table
 
4260
   we can determine how much it has changed after ALTER TABLE
3276
4261
   and whether we need to make a copy of the table, or just change
3277
4262
   the .frm file.
3278
4263
 
3290
4275
static
3291
4276
bool
3292
4277
compare_tables(THD *thd,
3293
 
               Table *table,
 
4278
               TABLE *table,
3294
4279
               Alter_info *alter_info,
3295
4280
                           HA_CREATE_INFO *create_info,
3296
 
               uint32_t order_num,
 
4281
               uint order_num,
3297
4282
               HA_ALTER_FLAGS *alter_flags,
3298
4283
               HA_ALTER_INFO *ha_alter_info,
3299
 
               uint32_t *table_changes)
 
4284
               uint *table_changes)
3300
4285
{
3301
4286
  Field **f_ptr, *field;
3302
 
  uint32_t table_changes_local= 0;
 
4287
  uint table_changes_local= 0;
3303
4288
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
3304
4289
  Create_field *new_field;
3305
4290
  KEY_PART_INFO *key_part;
3323
4308
      like to keep compare_tables() idempotent (not altering any
3324
4309
      of the arguments) we create a copy of alter_info here and
3325
4310
      pass it to mysql_prepare_create_table, then use the result
3326
 
      to evaluate possibility of fast ALTER Table, and then
 
4311
      to evaluate possibility of fast ALTER TABLE, and then
3327
4312
      destroy the copy.
3328
4313
    */
3329
4314
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
3330
4315
    THD *thd= table->in_use;
3331
 
    uint32_t db_options= 0; /* not used */
 
4316
    uint db_options= 0; /* not used */
3332
4317
    /* Create the prepared information. */
3333
4318
    if (mysql_prepare_create_table(thd, create_info,
3334
4319
                                   &tmp_alter_info,
3356
4341
 
3357
4342
  /*
3358
4343
    Some very basic checks. If number of fields changes, or the
3359
 
    handler, we need to run full ALTER Table. In the future
 
4344
    handler, we need to run full ALTER TABLE. In the future
3360
4345
    new fields can be added and old dropped without copy, but
3361
4346
    not yet.
3362
4347
 
3363
 
    Test also that engine was not given during ALTER Table, or
 
4348
    Test also that engine was not given during ALTER TABLE, or
3364
4349
    we are force to run regular alter table (copy).
3365
 
    E.g. ALTER Table tbl_name ENGINE=MyISAM.
 
4350
    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
3366
4351
 
3367
4352
    For the following ones we also want to run regular alter table:
3368
 
    ALTER Table tbl_name order_st BY ..
3369
 
    ALTER Table tbl_name CONVERT TO CHARACTER SET ..
 
4353
    ALTER TABLE tbl_name ORDER BY ..
 
4354
    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
3370
4355
 
3371
4356
    At the moment we can't handle altering temporary tables without a copy.
3372
 
    We also test if OPTIMIZE Table was given and was mapped to alter table.
 
4357
    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
3373
4358
    In that case we always do full copy.
3374
4359
 
3375
4360
    There was a bug prior to mysql-4.0.25. Number of null fields was
3431
4416
    /* Don't pack rows in old tables if the user has requested this. */
3432
4417
    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
3433
4418
        (new_field->flags & BLOB_FLAG) ||
3434
 
        (new_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
4419
        (new_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
3435
4420
      create_info->table_options|= HA_OPTION_PACK_RECORD;
3436
4421
 
3437
4422
    /* Check how fields have been modified */
3441
4426
      if (!(table_changes_local= field->is_equal(new_field)))
3442
4427
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3443
4428
 
3444
 
      /*
3445
 
        Check if the altered column is a stored virtual field.
3446
 
        TODO: Mark such a column with an alter flag only if
3447
 
        the expression functions are not equal. 
3448
 
      */
3449
 
      if (field->is_stored && field->vcol_info)
3450
 
        *alter_flags|= HA_ALTER_STORED_VCOL;
3451
 
 
3452
4429
      /* Check if field was renamed */
3453
4430
      field->flags&= ~FIELD_IS_RENAMED;
3454
4431
      if (my_strcasecmp(system_charset_info,
3645
4622
 
3646
4623
 
3647
4624
/*
3648
 
  Manages enabling/disabling of indexes for ALTER Table
 
4625
  Manages enabling/disabling of indexes for ALTER TABLE
3649
4626
 
3650
4627
  SYNOPSIS
3651
4628
    alter_table_manage_keys()
3660
4637
*/
3661
4638
 
3662
4639
static
3663
 
bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
 
4640
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
3664
4641
                             enum enum_enable_or_disable keys_onoff)
3665
4642
{
3666
4643
  int error= 0;
3678
4655
 
3679
4656
  if (error == HA_ERR_WRONG_COMMAND)
3680
4657
  {
3681
 
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4658
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3682
4659
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3683
4660
                        table->s->table_name.str);
3684
4661
    error= 0;
3689
4666
}
3690
4667
 
3691
4668
int create_temporary_table(THD *thd,
3692
 
                           Table *table,
 
4669
                           TABLE *table,
3693
4670
                           char *new_db,
3694
4671
                           char *tmp_name,
3695
4672
                           HA_CREATE_INFO *create_info,
3730
4707
    if (create_info->index_file_name)
3731
4708
    {
3732
4709
      /* Fix index_file_name to have 'tmp_name' as basename */
3733
 
      my_stpcpy(index_file, tmp_name);
 
4710
      strmov(index_file, tmp_name);
3734
4711
      create_info->index_file_name=fn_same(index_file,
3735
4712
                                           create_info->index_file_name,
3736
4713
                                           1);
3738
4715
    if (create_info->data_file_name)
3739
4716
    {
3740
4717
      /* Fix data_file_name to have 'tmp_name' as basename */
3741
 
      my_stpcpy(data_file, tmp_name);
 
4718
      strmov(data_file, tmp_name);
3742
4719
      create_info->data_file_name=fn_same(data_file,
3743
4720
                                          create_info->data_file_name,
3744
4721
                                          1);
3780
4757
    The temporary table is created without storing it in any storage engine
3781
4758
    and is opened only to get the table struct and frm file reference.
3782
4759
*/
3783
 
Table *create_altered_table(THD *thd,
3784
 
                            Table *table,
 
4760
TABLE *create_altered_table(THD *thd,
 
4761
                            TABLE *table,
3785
4762
                            char *new_db,
3786
4763
                            HA_CREATE_INFO *create_info,
3787
4764
                            Alter_info *alter_info,
3789
4766
{
3790
4767
  int error;
3791
4768
  HA_CREATE_INFO altered_create_info(*create_info);
3792
 
  Table *altered_table;
 
4769
  TABLE *altered_table;
3793
4770
  char tmp_name[80];
3794
4771
  char path[FN_REFLEN];
3795
4772
 
3843
4820
    the table.
3844
4821
*/
3845
4822
int mysql_fast_or_online_alter_table(THD *thd,
3846
 
                                     Table *table,
3847
 
                                     Table *altered_table,
 
4823
                                     TABLE *table,
 
4824
                                     TABLE *altered_table,
3848
4825
                                     HA_CREATE_INFO *create_info,
3849
4826
                                     HA_ALTER_INFO *alter_info,
3850
4827
                                     HA_ALTER_FLAGS *ha_alter_flags,
3852
4829
{
3853
4830
  int error= 0;
3854
4831
  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER)?true:false;
3855
 
  Table *t_table;
 
4832
  TABLE *t_table;
3856
4833
 
3857
4834
  if (online)
3858
4835
  {
3887
4864
    The final .frm file is already created as a temporary file
3888
4865
    and will be renamed to the original table name.
3889
4866
  */
3890
 
  pthread_mutex_lock(&LOCK_open);
 
4867
  VOID(pthread_mutex_lock(&LOCK_open));
3891
4868
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3892
4869
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3893
4870
                          keys_onoff);
3901
4878
                         table->s->table_name.str, FN_FROM_IS_TMP))
3902
4879
  {
3903
4880
    error= 1;
3904
 
    pthread_mutex_unlock(&LOCK_open);
 
4881
    VOID(pthread_mutex_unlock(&LOCK_open));
3905
4882
    goto err;
3906
4883
  }
3907
4884
  broadcast_refresh();
3908
 
  pthread_mutex_unlock(&LOCK_open);
 
4885
  VOID(pthread_mutex_unlock(&LOCK_open));
3909
4886
 
3910
4887
  /*
3911
 
    The ALTER Table is always in its own transaction.
 
4888
    The ALTER TABLE is always in its own transaction.
3912
4889
    Commit must not be called while LOCK_open is locked. It could call
3913
4890
    wait_if_global_read_lock(), which could create a deadlock if called
3914
4891
    with LOCK_open.
3921
4898
    goto err;
3922
4899
  if (online)
3923
4900
  {
3924
 
    pthread_mutex_lock(&LOCK_open);
 
4901
    VOID(pthread_mutex_lock(&LOCK_open));
3925
4902
    if (reopen_table(table))
3926
4903
    {
3927
4904
      error= -1;
3928
4905
      goto err;
3929
4906
    }
3930
 
    pthread_mutex_unlock(&LOCK_open);
 
4907
    VOID(pthread_mutex_unlock(&LOCK_open));
3931
4908
    t_table= table;
3932
4909
 
3933
4910
   /*
3941
4918
 
3942
4919
    /*
3943
4920
      We are going to reopen table down on the road, so we have to restore
3944
 
      state of the Table object which we used for obtaining of handler
 
4921
      state of the TABLE object which we used for obtaining of handler
3945
4922
      object to make it suitable for reopening.
3946
4923
    */
3947
4924
    assert(t_table == table);
3948
4925
    table->open_placeholder= 1;
3949
 
    pthread_mutex_lock(&LOCK_open);
 
4926
    VOID(pthread_mutex_lock(&LOCK_open));
3950
4927
    close_handle_and_leave_table_as_lock(table);
3951
 
    pthread_mutex_unlock(&LOCK_open);
 
4928
    VOID(pthread_mutex_unlock(&LOCK_open));
3952
4929
  }
3953
4930
 
3954
4931
 err:
3959
4936
 
3960
4937
 
3961
4938
/**
3962
 
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
 
4939
  Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
3963
4940
 
3964
 
  This function transforms parse output of ALTER Table - lists of
 
4941
  This function transforms parse output of ALTER TABLE - lists of
3965
4942
  columns and keys to add, drop or modify into, essentially,
3966
4943
  CREATE TABLE definition - a list of columns and keys of the new
3967
4944
  table. While doing so, it also performs some (bug not all)
3968
4945
  semantic checks.
3969
4946
 
3970
4947
  This function is invoked when we know that we're going to
3971
 
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
 
4948
  perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
3972
4949
  is not possible, perhaps because the ALTER statement contains
3973
4950
  instructions that require change in table data, not only in
3974
4951
  table definition or indexes.
3979
4956
                              Used as an interface to the storage engine
3980
4957
                              to acquire additional information about
3981
4958
                              the original table.
3982
 
  @param[in,out]  create_info A blob with CREATE/ALTER Table
 
4959
  @param[in,out]  create_info A blob with CREATE/ALTER TABLE
3983
4960
                              parameters
3984
4961
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
3985
4962
                              Originally create_info was used only in
3986
 
                              CREATE TABLE and alter_info only in ALTER Table.
 
4963
                              CREATE TABLE and alter_info only in ALTER TABLE.
3987
4964
                              But since ALTER might end-up doing CREATE,
3988
4965
                              this distinction is gone and we just carry
3989
4966
                              around two structures.
3995
4972
    Prepares alter_info->create_list and alter_info->key_list with
3996
4973
    columns and keys of the new table.
3997
4974
  @retval true   error, out of memory or a semantical error in ALTER
3998
 
                 Table instructions
 
4975
                 TABLE instructions
3999
4976
  @retval false  success
4000
4977
*/
4001
4978
 
4002
4979
static bool
4003
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
4980
mysql_prepare_alter_table(THD *thd, TABLE *table,
4004
4981
                          HA_CREATE_INFO *create_info,
4005
4982
                          Alter_info *alter_info)
4006
4983
{
4015
4992
  List_iterator<Create_field> find_it(new_create_list);
4016
4993
  List_iterator<Create_field> field_it(new_create_list);
4017
4994
  List<Key_part_spec> key_parts;
4018
 
  uint32_t db_create_options= (table->s->db_create_options
 
4995
  uint db_create_options= (table->s->db_create_options
4019
4996
                           & ~(HA_OPTION_PACK_RECORD));
4020
 
  uint32_t used_fields= create_info->used_fields;
 
4997
  uint used_fields= create_info->used_fields;
4021
4998
  KEY *key_info=table->key_info;
4022
4999
  bool rc= true;
4023
5000
 
4030
5007
    create_info->max_rows= table->s->max_rows;
4031
5008
  if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
4032
5009
    create_info->avg_row_length= table->s->avg_row_length;
4033
 
  if (!(used_fields & HA_CREATE_USED_BLOCK_SIZE))
4034
 
    create_info->block_size= table->s->block_size;
4035
5010
  if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
4036
5011
    create_info->default_table_charset= table->s->table_charset;
4037
5012
  if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
4042
5017
  }
4043
5018
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
4044
5019
    create_info->key_block_size= table->s->key_block_size;
 
5020
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
 
5021
    create_info->transactional= table->s->transactional;
4045
5022
 
4046
5023
  restore_record(table, s->default_values);     // Empty record for DEFAULT
4047
5024
  Create_field *def;
4052
5029
  Field **f_ptr,*field;
4053
5030
  for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
4054
5031
    {
 
5032
    if (field->type() == MYSQL_TYPE_STRING)
 
5033
      create_info->varchar= true;
4055
5034
    /* Check if field should be dropped */
4056
5035
    Alter_drop *drop;
4057
5036
    drop_it.rewind();
4086
5065
    if (def)
4087
5066
    {                                           // Field is changed
4088
5067
      def->field=field;
4089
 
      if (field->is_stored != def->is_stored)
4090
 
      {
4091
 
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
4092
 
                 MYF(0),
4093
 
                 "Changing the STORED status");
4094
 
        goto err;
4095
 
      }
4096
5068
      if (!def->after)
4097
5069
        {
4098
5070
        new_create_list.push_back(def);
4116
5088
        }
4117
5089
      if (alter)
4118
5090
        {
4119
 
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
 
5091
        if (def->sql_type == MYSQL_TYPE_BLOB)
4120
5092
        {
4121
5093
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
4122
5094
          goto err;
4142
5114
      either has a default value or the '0000-00-00' is allowed by the
4143
5115
      set sql mode.
4144
5116
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4145
 
      flag to allow ALTER Table only if the table to be altered is empty.
 
5117
      flag to allow ALTER TABLE only if the table to be altered is empty.
4146
5118
      */
4147
 
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
4148
 
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
 
5119
    if ((def->sql_type == MYSQL_TYPE_NEWDATE ||
 
5120
         def->sql_type == MYSQL_TYPE_DATETIME) &&
4149
5121
         !alter_info->datetime_field &&
4150
5122
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4151
5123
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
4174
5146
      find_it.after(def);                       // Put element after this
4175
5147
      /*
4176
5148
        XXX: hack for Bug#28427.
4177
 
        If column order has changed, force OFFLINE ALTER Table
 
5149
        If column order has changed, force OFFLINE ALTER TABLE
4178
5150
        without querying engine capabilities.  If we ever have an
4179
 
        engine that supports online ALTER Table CHANGE COLUMN
 
5151
        engine that supports online ALTER TABLE CHANGE COLUMN
4180
5152
        <name> AFTER <name1> (Falcon?), this fix will effectively
4181
5153
        disable the capability.
4182
5154
        TODO: detect the situation in compare_tables, behave based
4208
5180
    for which some fields exists.
4209
5181
    */
4210
5182
 
4211
 
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
 
5183
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
4212
5184
    {
4213
5185
    char *key_name= key_info->name;
4214
5186
    Alter_drop *drop;
4227
5199
 
4228
5200
    KEY_PART_INFO *key_part= key_info->key_part;
4229
5201
    key_parts.empty();
4230
 
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
 
5202
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
4231
5203
    {
4232
5204
      if (!key_part->field)
4233
5205
        continue;                               // Wrong field (from UNIREG)
4248
5220
      }
4249
5221
      if (!cfield)
4250
5222
        continue;                               // Field is removed
4251
 
      uint32_t key_part_length=key_part->length;
 
5223
      uint key_part_length=key_part->length;
4252
5224
      if (cfield->field)                        // Not new field
4253
5225
      {
4254
5226
        /*
4281
5253
      KEY_CREATE_INFO key_create_info;
4282
5254
      Key *key;
4283
5255
      enum Key::Keytype key_type;
4284
 
      memset(&key_create_info, 0, sizeof(key_create_info));
 
5256
      bzero((char*) &key_create_info, sizeof(key_create_info));
4285
5257
 
4286
5258
      key_create_info.algorithm= key_info->algorithm;
4287
5259
      if (key_info->flags & HA_USES_BLOCK_SIZE)
4310
5282
    Key *key;
4311
5283
    while ((key=key_it++))                      // Add new keys
4312
5284
    {
4313
 
      if (key->type == Key::FOREIGN_KEY &&
4314
 
          ((Foreign_key *)key)->validate(new_create_list))
4315
 
        goto err;
4316
5285
      if (key->type != Key::FOREIGN_KEY)
4317
5286
        new_key_list.push_back(key);
4318
5287
      if (key->name.str &&
4381
5350
      table_list       The table to change.
4382
5351
      alter_info       Lists of fields, keys to be changed, added
4383
5352
                       or dropped.
4384
 
      order_num        How many order_st BY fields has been specified.
4385
 
      order            List of fields to order_st BY.
4386
 
      ignore           Whether we have ALTER IGNORE Table
 
5353
      order_num        How many ORDER BY fields has been specified.
 
5354
      order            List of fields to ORDER BY.
 
5355
      ignore           Whether we have ALTER IGNORE TABLE
4387
5356
 
4388
5357
  DESCRIPTION
4389
5358
    This is a veery long function and is everything but the kitchen sink :)
4390
 
    It is used to alter a table and not only by ALTER Table but also
 
5359
    It is used to alter a table and not only by ALTER TABLE but also
4391
5360
    CREATE|DROP INDEX are mapped on this function.
4392
5361
 
4393
 
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
 
5362
    When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
4394
5363
    or both, then this function short cuts its operation by renaming
4395
5364
    the table and/or enabling/disabling the keys. In this case, the FRM is
4396
5365
    not changed, directly by mysql_alter_table. However, if there is a
4412
5381
 
4413
5382
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
4414
5383
                       HA_CREATE_INFO *create_info,
4415
 
                       TableList *table_list,
 
5384
                       TABLE_LIST *table_list,
4416
5385
                       Alter_info *alter_info,
4417
 
                       uint32_t order_num, order_st *order, bool ignore)
 
5386
                       uint order_num, ORDER *order, bool ignore)
4418
5387
{
4419
 
  Table *table, *new_table=0, *name_lock= 0;;
 
5388
  TABLE *table, *new_table=0, *name_lock= 0;;
4420
5389
  int error= 0;
4421
5390
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4422
5391
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4424
5393
  ha_rows copied= 0,deleted= 0;
4425
5394
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4426
5395
  legacy_db_type table_type;
 
5396
  frm_type_enum frm_type;
4427
5397
 
4428
5398
  if (table_list && table_list->schema_table)
4429
5399
  {
4436
5406
    to simplify further comparisons: we want to see if it's a RENAME
4437
5407
    later just by comparing the pointers, avoiding the need for strcmp.
4438
5408
  */
4439
 
  thd->set_proc_info("init");
 
5409
  thd_proc_info(thd, "init");
4440
5410
  table_name=table_list->table_name;
4441
5411
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4442
5412
  db=table_list->db;
4446
5416
 
4447
5417
  mysql_ha_rm_tables(thd, table_list, false);
4448
5418
 
4449
 
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
 
5419
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
4450
5420
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4451
5421
    /* Conditionally writes to binlog. */
4452
5422
    return(mysql_discard_or_import_tablespace(thd,table_list,
4453
5423
                                              alter_info->tablespace_op));
4454
5424
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
4455
 
           "/", table_name, reg_ext, NULL);
 
5425
           "/", table_name, reg_ext, NullS);
4456
5426
  (void) unpack_filename(new_name_buff, new_name_buff);
4457
5427
  /*
4458
5428
    If this is just a rename of a view, short cut to the
4459
5429
    following scenario: 1) lock LOCK_open 2) do a RENAME
4460
5430
    2) unlock LOCK_open.
4461
5431
    This is a copy-paste added to make sure
4462
 
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
 
5432
    ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
4463
5433
    as an independent branch in mysql_execute_command. The need
4464
 
    for a copy-paste arose because the main code flow of ALTER Table
 
5434
    for a copy-paste arose because the main code flow of ALTER TABLE
4465
5435
    ... RENAME tries to use open_ltable, which does not work for views
4466
5436
    (open_ltable was never modified to merge table lists of child tables
4467
5437
    into the main table list, like open_tables does).
4468
5438
    This code is wrong and will be removed, please do not copy.
4469
5439
  */
4470
 
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
 
5440
  frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
4471
5441
 
4472
5442
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
4473
5443
    return(true);
4474
5444
  table->use_all_columns();
4475
5445
 
 
5446
  /*
 
5447
    Prohibit changing of the UNION list of a non-temporary MERGE table
 
5448
    under LOCK tables. It would be quite difficult to reuse a shrinked
 
5449
    set of tables from the old table or to open a new TABLE object for
 
5450
    an extended list and verify that they belong to locked tables.
 
5451
  */
 
5452
  if (thd->locked_tables &&
 
5453
      (create_info->used_fields & HA_CREATE_USED_UNION) &&
 
5454
      (table->s->tmp_table == NO_TMP_TABLE))
 
5455
  {
 
5456
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
5457
    return(true);
 
5458
  }
 
5459
 
4476
5460
  /* Check that we are not trying to rename to an existing table */
4477
5461
  if (new_name)
4478
5462
  {
4479
 
    my_stpcpy(new_name_buff,new_name);
4480
 
    my_stpcpy(new_alias= new_alias_buff, new_name);
 
5463
    strmov(new_name_buff,new_name);
 
5464
    strmov(new_alias= new_alias_buff, new_name);
4481
5465
    if (lower_case_table_names)
4482
5466
    {
4483
5467
      if (lower_case_table_names != 2)
4543
5527
    goto err;
4544
5528
  new_db_type= create_info->db_type;
4545
5529
 
4546
 
  if (new_db_type != old_db_type &&
 
5530
  if (new_db_type != old_db_type ||
4547
5531
      !table->file->can_switch_engines())
4548
5532
  {
4549
 
    assert(0);
4550
5533
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
4551
5534
    goto err;
4552
5535
  }
4561
5544
    goto err;
4562
5545
  }
4563
5546
 
4564
 
  thd->set_proc_info("setup");
 
5547
  thd_proc_info(thd, "setup");
4565
5548
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4566
5549
      !table->s->tmp_table) // no need to touch frm
4567
5550
  {
4571
5554
    case ENABLE:
4572
5555
      /*
4573
5556
        wait_while_table_is_used() ensures that table being altered is
4574
 
        opened only by this thread and that Table::TABLE_SHARE::version
4575
 
        of Table object corresponding to this table is 0.
 
5557
        opened only by this thread and that TABLE::TABLE_SHARE::version
 
5558
        of TABLE object corresponding to this table is 0.
4576
5559
        The latter guarantees that no DML statement will open this table
4577
 
        until ALTER Table finishes (i.e. until close_thread_tables())
 
5560
        until ALTER TABLE finishes (i.e. until close_thread_tables())
4578
5561
        while the fact that the table is still open gives us protection
4579
5562
        from concurrent DDL statements.
4580
5563
      */
4581
 
      pthread_mutex_lock(&LOCK_open);
 
5564
      VOID(pthread_mutex_lock(&LOCK_open));
4582
5565
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4583
 
      pthread_mutex_unlock(&LOCK_open);
 
5566
      VOID(pthread_mutex_unlock(&LOCK_open));
 
5567
      DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
4584
5568
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4585
5569
      /* COND_refresh will be signaled in close_thread_tables() */
4586
5570
      break;
4587
5571
    case DISABLE:
4588
 
      pthread_mutex_lock(&LOCK_open);
 
5572
      VOID(pthread_mutex_lock(&LOCK_open));
4589
5573
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4590
 
      pthread_mutex_unlock(&LOCK_open);
 
5574
      VOID(pthread_mutex_unlock(&LOCK_open));
4591
5575
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4592
5576
      /* COND_refresh will be signaled in close_thread_tables() */
4593
5577
      break;
4599
5583
    if (error == HA_ERR_WRONG_COMMAND)
4600
5584
    {
4601
5585
      error= 0;
4602
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5586
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4603
5587
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4604
5588
                          table->alias);
4605
5589
    }
4606
5590
 
4607
 
    pthread_mutex_lock(&LOCK_open);
 
5591
    VOID(pthread_mutex_lock(&LOCK_open));
4608
5592
    /*
4609
5593
      Unlike to the above case close_cached_table() below will remove ALL
4610
 
      instances of Table from table cache (it will also remove table lock
 
5594
      instances of TABLE from table cache (it will also remove table lock
4611
5595
      held by this thread). So to make actual table renaming and writing
4612
5596
      to binlog atomic we have to put them into the same critical section
4613
5597
      protected by LOCK_open mutex. This also removes gap for races between
4616
5600
 
4617
5601
    if (!error && (new_name != table_name || new_db != db))
4618
5602
    {
4619
 
      thd->set_proc_info("rename");
 
5603
      thd_proc_info(thd, "rename");
4620
5604
      /*
4621
5605
        Then do a 'simple' rename of the table. First we need to close all
4622
5606
        instances of 'source' table.
4642
5626
          error= -1;
4643
5627
        else if (0)
4644
5628
      {
4645
 
          mysql_rename_table(old_db_type, new_db, new_alias, db,
4646
 
                             table_name, 0);
 
5629
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
 
5630
                                  table_name, 0));
4647
5631
          error= -1;
4648
5632
      }
4649
5633
    }
4652
5636
    if (error == HA_ERR_WRONG_COMMAND)
4653
5637
  {
4654
5638
      error= 0;
4655
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5639
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4656
5640
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4657
5641
                          table->alias);
4658
5642
  }
4669
5653
    }
4670
5654
    if (name_lock)
4671
5655
      unlink_open_table(thd, name_lock, false);
4672
 
    pthread_mutex_unlock(&LOCK_open);
 
5656
    VOID(pthread_mutex_unlock(&LOCK_open));
4673
5657
    table_list->table= NULL;                    // For query cache
4674
5658
    return(error);
4675
5659
  }
4677
5661
  /* We have to do full alter table. */
4678
5662
 
4679
5663
    /*
4680
 
    If the old table had partitions and we are doing ALTER Table ...
 
5664
    If the old table had partitions and we are doing ALTER TABLE ...
4681
5665
    engine= <new_engine>, the new table must preserve the original
4682
5666
    partitioning. That means that the new engine is still the
4683
5667
    partitioning engine, not the engine specified in the parser.
4709
5693
 
4710
5694
  if (alter_info->build_method != HA_BUILD_OFFLINE)
4711
5695
  {
4712
 
    Table *altered_table= 0;
 
5696
    TABLE *altered_table= 0;
4713
5697
    HA_ALTER_INFO ha_alter_info;
4714
5698
    HA_ALTER_FLAGS ha_alter_flags;
4715
 
    uint32_t table_changes= IS_EQUAL_YES;
 
5699
    uint table_changes= IS_EQUAL_YES;
4716
5700
    bool need_copy_table= true;
4717
5701
    /* Check how much the tables differ. */
4718
5702
    if (compare_tables(thd, table, alter_info,
4761
5745
        /*
4762
5746
          @todo: Currently we always acquire an exclusive name
4763
5747
          lock on the table metadata when performing fast or online
4764
 
          ALTER Table. In future we may consider this unnecessary,
 
5748
          ALTER TABLE. In future we may consider this unnecessary,
4765
5749
          and narrow the scope of the exclusive name lock to only
4766
5750
          cover manipulation with .frms. Storage engine API
4767
5751
          call check_if_supported_alter has provision for this
4785
5769
      }
4786
5770
 
4787
5771
    }
4788
 
    /* TODO need to check if changes can be handled as fast ALTER Table */
 
5772
    /* TODO need to check if changes can be handled as fast ALTER TABLE */
4789
5773
    if (!altered_table)
4790
5774
      need_copy_table= true;
4791
5775
 
4843
5827
  /* Open the table so we need to copy the data to it. */
4844
5828
  if (table->s->tmp_table)
4845
5829
  {
4846
 
    TableList tbl;
4847
 
    memset(&tbl, 0, sizeof(tbl));
 
5830
    TABLE_LIST tbl;
 
5831
    bzero((void*) &tbl, sizeof(tbl));
4848
5832
    tbl.db= new_db;
4849
5833
    tbl.table_name= tbl.alias= tmp_name;
4850
5834
    /* Table is in thd->temporary_tables */
4851
 
    new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
 
5835
    new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
 
5836
                          MYSQL_LOCK_IGNORE_FLUSH);
4852
5837
  }
4853
5838
  else
4854
5839
  {
4865
5850
  /* Copy the data if necessary. */
4866
5851
  thd->count_cuted_fields= CHECK_FIELD_WARN;    // calc cuted fields
4867
5852
  thd->cuted_fields=0L;
4868
 
  thd->set_proc_info("copy to tmp table");
 
5853
  thd_proc_info(thd, "copy to tmp table");
4869
5854
  copied=deleted=0;
4870
5855
  /*
4871
5856
    We do not copy data for MERGE tables. Only the children have data.
4873
5858
  */
4874
5859
  if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
4875
5860
  {
4876
 
    /* We don't want update TIMESTAMP fields during ALTER Table. */
 
5861
    /* We don't want update TIMESTAMP fields during ALTER TABLE. */
4877
5862
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
4878
5863
    new_table->next_number_field=new_table->found_next_number_field;
4879
5864
    error= copy_data_between_tables(table, new_table,
4884
5869
  }
4885
5870
  else
4886
5871
  {
4887
 
    pthread_mutex_lock(&LOCK_open);
 
5872
    VOID(pthread_mutex_lock(&LOCK_open));
4888
5873
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4889
 
    pthread_mutex_unlock(&LOCK_open);
 
5874
    VOID(pthread_mutex_unlock(&LOCK_open));
4890
5875
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4891
5876
                            alter_info->keys_onoff);
4892
5877
    error= ha_autocommit_or_rollback(thd, 0);
4924
5909
      Note that MERGE tables do not have their children attached here.
4925
5910
    */
4926
5911
    intern_close_table(new_table);
4927
 
    free(new_table);
 
5912
    my_free(new_table,MYF(0));
4928
5913
  }
4929
 
  pthread_mutex_lock(&LOCK_open);
 
5914
  VOID(pthread_mutex_lock(&LOCK_open));
4930
5915
  if (error)
4931
5916
  {
4932
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4933
 
    pthread_mutex_unlock(&LOCK_open);
 
5917
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5918
    VOID(pthread_mutex_unlock(&LOCK_open));
4934
5919
    goto err;
4935
5920
  }
4936
5921
 
4941
5926
       with exclusive name-locks.
4942
5927
    3) Rename the old table to a temp name, rename the new one to the
4943
5928
       old name.
4944
 
    4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
 
5929
    4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
4945
5930
       we reopen new version of table.
4946
5931
    5) Write statement to the binary log.
4947
 
    6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
 
5932
    6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
4948
5933
       remove name-locks from list of open tables and table cache.
4949
5934
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
4950
5935
       call to remove name-locks from table cache and list of open table.
4951
5936
  */
4952
5937
 
4953
 
  thd->set_proc_info("rename result table");
 
5938
  thd_proc_info(thd, "rename result table");
4954
5939
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
4955
5940
           current_pid, thd->thread_id);
4956
5941
  if (lower_case_table_names)
4967
5952
    mysql_rename_table(), because we just juggle with the FRM and nothing
4968
5953
    more. If we have an intermediate table, then we notify the SE that
4969
5954
    it should become the actual table. Later, we will recycle the old table.
4970
 
    However, in case of ALTER Table RENAME there might be no intermediate
 
5955
    However, in case of ALTER TABLE RENAME there might be no intermediate
4971
5956
    table. This is when the old and new tables are compatible, according to
4972
5957
    compare_table(). Then, we need one additional call to
4973
5958
    mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
4979
5964
                         FN_TO_IS_TMP))
4980
5965
  {
4981
5966
    error=1;
4982
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
5967
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4983
5968
  }
4984
5969
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
4985
5970
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
4986
5971
  {
4987
5972
    /* Try to get everything back. */
4988
5973
    error=1;
4989
 
    quick_rm_table(new_db_type,new_db,new_alias, 0);
4990
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4991
 
    mysql_rename_table(old_db_type, db, old_name, db, alias,
4992
 
                       FN_FROM_IS_TMP);
 
5974
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
 
5975
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5976
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
 
5977
                            FN_FROM_IS_TMP));
4993
5978
  }
4994
5979
 
4995
5980
  if (error)
4998
5983
    goto err_with_placeholders;
4999
5984
  }
5000
5985
 
5001
 
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
 
5986
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
5002
5987
 
5003
5988
end_online:
5004
5989
  if (thd->locked_tables && new_name == table_name && new_db == db)
5009
5994
    if (error)
5010
5995
      goto err_with_placeholders;
5011
5996
  }
5012
 
  pthread_mutex_unlock(&LOCK_open);
5013
 
 
5014
 
  thd->set_proc_info("end");
 
5997
  VOID(pthread_mutex_unlock(&LOCK_open));
 
5998
 
 
5999
  thd_proc_info(thd, "end");
 
6000
 
 
6001
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
 
6002
                      thd->query, thd->query_length,
 
6003
                      db, table_name);
5015
6004
 
5016
6005
  assert(!(mysql_bin_log.is_open() &&
5017
6006
                thd->current_stmt_binlog_row_based &&
5026
6015
      shutdown. But we do not need to attach MERGE children.
5027
6016
    */
5028
6017
    char path[FN_REFLEN];
5029
 
    Table *t_table;
 
6018
    TABLE *t_table;
5030
6019
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
5031
6020
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
5032
6021
    if (t_table)
5033
6022
    {
5034
6023
      intern_close_table(t_table);
5035
 
      free(t_table);
 
6024
      my_free(t_table, MYF(0));
5036
6025
    }
5037
6026
    else
5038
 
      sql_print_warning(_("Could not open table %s.%s after rename\n"),
 
6027
      sql_print_warning("Could not open table %s.%s after rename\n",
5039
6028
                        new_db,table_name);
5040
6029
    ha_flush_logs(old_db_type);
5041
6030
  }
5044
6033
  if (thd->locked_tables && (new_name != table_name || new_db != db))
5045
6034
  {
5046
6035
    /*
5047
 
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
 
6036
      If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
5048
6037
      to remove placeholders for the old table and for the target table
5049
6038
      from the list of open tables and table cache. If we are not under
5050
6039
      LOCK TABLES we can rely on close_thread_tables() doing this job.
5070
6059
    close_temporary_table(thd, new_table, 1, 1);
5071
6060
  }
5072
6061
  else
5073
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
6062
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
5074
6063
 
5075
6064
err:
5076
6065
  /*
5082
6071
  if (alter_info->error_if_not_empty && thd->row_count)
5083
6072
  {
5084
6073
    const char *f_val= 0;
5085
 
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
 
6074
    enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
5086
6075
    switch (alter_info->datetime_field->sql_type)
5087
6076
    {
5088
 
      case DRIZZLE_TYPE_NEWDATE:
 
6077
      case MYSQL_TYPE_NEWDATE:
5089
6078
        f_val= "0000-00-00";
5090
 
        t_type= DRIZZLE_TIMESTAMP_DATE;
 
6079
        t_type= MYSQL_TIMESTAMP_DATE;
5091
6080
        break;
5092
 
      case DRIZZLE_TYPE_DATETIME:
 
6081
      case MYSQL_TYPE_DATETIME:
5093
6082
        f_val= "0000-00-00 00:00:00";
5094
 
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
 
6083
        t_type= MYSQL_TIMESTAMP_DATETIME;
5095
6084
        break;
5096
6085
      default:
5097
6086
        /* Shouldn't get here. */
5099
6088
    }
5100
6089
    bool save_abort_on_warning= thd->abort_on_warning;
5101
6090
    thd->abort_on_warning= true;
5102
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
6091
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
5103
6092
                                 f_val, strlength(f_val), t_type,
5104
6093
                                 alter_info->datetime_field->field_name);
5105
6094
    thd->abort_on_warning= save_abort_on_warning;
5121
6110
  unlink_open_table(thd, table, false);
5122
6111
  if (name_lock)
5123
6112
    unlink_open_table(thd, name_lock, false);
5124
 
  pthread_mutex_unlock(&LOCK_open);
 
6113
  VOID(pthread_mutex_unlock(&LOCK_open));
5125
6114
  return(true);
5126
6115
}
5127
6116
/* mysql_alter_table */
5128
6117
 
5129
6118
static int
5130
 
copy_data_between_tables(Table *from,Table *to,
 
6119
copy_data_between_tables(TABLE *from,TABLE *to,
5131
6120
                         List<Create_field> &create,
5132
6121
                         bool ignore,
5133
 
                         uint32_t order_num, order_st *order,
 
6122
                         uint order_num, ORDER *order,
5134
6123
                         ha_rows *copied,
5135
6124
                         ha_rows *deleted,
5136
6125
                         enum enum_enable_or_disable keys_onoff,
5140
6129
  Copy_field *copy,*copy_end;
5141
6130
  ulong found_count,delete_count;
5142
6131
  THD *thd= current_thd;
5143
 
  uint32_t length= 0;
 
6132
  uint length= 0;
5144
6133
  SORT_FIELD *sortorder;
5145
6134
  READ_RECORD info;
5146
 
  TableList   tables;
 
6135
  TABLE_LIST   tables;
5147
6136
  List<Item>   fields;
5148
6137
  List<Item>   all_fields;
5149
6138
  ha_rows examined_rows;
5150
6139
  bool auto_increment_field_copied= 0;
5151
6140
  ulong save_sql_mode;
5152
 
  uint64_t prev_insert_id;
 
6141
  ulonglong prev_insert_id;
5153
6142
 
5154
6143
  /*
5155
6144
    Turn off recovery logging since rollback of an alter table is to
5187
6176
    if (def->field)
5188
6177
    {
5189
6178
      if (*ptr == to->next_number_field)
 
6179
      {
5190
6180
        auto_increment_field_copied= true;
5191
 
 
 
6181
        /*
 
6182
          If we are going to copy contents of one auto_increment column to
 
6183
          another auto_increment column it is sensible to preserve zeroes.
 
6184
          This condition also covers case when we are don't actually alter
 
6185
          auto_increment column.
 
6186
        */
 
6187
        if (def->field == from->found_next_number_field)
 
6188
          thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
 
6189
      }
5192
6190
      (copy_end++)->set(*ptr,def->field,0);
5193
6191
    }
5194
6192
 
5200
6198
  {
5201
6199
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5202
6200
    {
5203
 
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
6201
      char warn_buff[MYSQL_ERRMSG_SIZE];
5204
6202
      snprintf(warn_buff, sizeof(warn_buff), 
5205
 
               _("order_st BY ignored because there is a user-defined clustered "
5206
 
                 "index in the table '%-.192s'"),
5207
 
               from->s->table_name.str);
5208
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
6203
               "ORDER BY ignored as there is a user-defined clustered index"
 
6204
               " in the table '%-.192s'", from->s->table_name.str);
 
6205
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5209
6206
                   warn_buff);
5210
6207
    }
5211
6208
    else
5212
6209
    {
5213
6210
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5214
6211
                                                MYF(MY_FAE | MY_ZEROFILL));
5215
 
      memset(&tables, 0, sizeof(tables));
 
6212
      bzero((char *) &tables, sizeof(tables));
5216
6213
      tables.table= from;
5217
6214
      tables.alias= tables.table_name= from->s->table_name.str;
5218
6215
      tables.db= from->s->db.str;
5265
6262
      copy_ptr->do_copy(copy_ptr);
5266
6263
    }
5267
6264
    prev_insert_id= to->file->next_insert_id;
5268
 
    update_virtual_fields_marked_for_write(to, false);
5269
6265
    error=to->file->ha_write_row(to->record[0]);
5270
6266
    to->auto_increment_field_not_null= false;
5271
6267
    if (error)
5275
6271
      {
5276
6272
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
5277
6273
         {
5278
 
           uint32_t key_nr= to->file->get_dup_key(error);
 
6274
           uint key_nr= to->file->get_dup_key(error);
5279
6275
           if ((int) key_nr >= 0)
5280
6276
           {
5281
6277
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
5347
6343
 RETURN
5348
6344
    Like mysql_alter_table().
5349
6345
*/
5350
 
bool mysql_recreate_table(THD *thd, TableList *table_list)
 
6346
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
5351
6347
{
5352
6348
  HA_CREATE_INFO create_info;
5353
6349
  Alter_info alter_info;
5359
6355
  */
5360
6356
  table_list->table= NULL;
5361
6357
 
5362
 
  memset(&create_info, 0, sizeof(create_info));
 
6358
  bzero((char*) &create_info, sizeof(create_info));
5363
6359
  create_info.row_type=ROW_TYPE_NOT_USED;
5364
6360
  create_info.default_table_charset=default_charset_info;
5365
6361
  /* Force alter table to recreate table */
5366
6362
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5367
 
  return(mysql_alter_table(thd, NULL, NULL, &create_info,
 
6363
  return(mysql_alter_table(thd, NullS, NullS, &create_info,
5368
6364
                                table_list, &alter_info, 0,
5369
 
                                (order_st *) 0, 0));
 
6365
                                (ORDER *) 0, 0));
5370
6366
}
5371
6367
 
5372
6368
 
5373
 
bool mysql_checksum_table(THD *thd, TableList *tables,
 
6369
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
5374
6370
                          HA_CHECK_OPT *check_opt)
5375
6371
{
5376
 
  TableList *table;
 
6372
  TABLE_LIST *table;
5377
6373
  List<Item> field_list;
5378
6374
  Item *item;
5379
6375
  Protocol *protocol= thd->protocol;
5380
6376
 
5381
6377
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5382
6378
  item->maybe_null= 1;
5383
 
  field_list.push_back(item= new Item_int("Checksum", (int64_t) 1,
 
6379
  field_list.push_back(item= new Item_int("Checksum", (longlong) 1,
5384
6380
                                          MY_INT64_NUM_DECIMAL_DIGITS));
5385
6381
  item->maybe_null= 1;
5386
6382
  if (protocol->send_fields(&field_list,
5391
6387
  for (table= tables; table; table= table->next_local)
5392
6388
  {
5393
6389
    char table_name[NAME_LEN*2+2];
5394
 
    Table *t;
 
6390
    TABLE *t;
5395
6391
 
5396
 
    strxmov(table_name, table->db ,".", table->table_name, NULL);
 
6392
    strxmov(table_name, table->db ,".", table->table_name, NullS);
5397
6393
 
5398
6394
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5399
6395
    thd->clear_error();                 // these errors shouldn't get client
5411
6407
    {
5412
6408
      if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
5413
6409
          !(check_opt->flags & T_EXTEND))
5414
 
        protocol->store((uint64_t)t->file->checksum());
 
6410
        protocol->store((ulonglong)t->file->checksum());
5415
6411
      else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
5416
6412
               (check_opt->flags & T_QUICK))
5417
6413
        protocol->store_null();
5419
6415
      {
5420
6416
        /* calculating table's checksum */
5421
6417
        ha_checksum crc= 0;
5422
 
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
 
6418
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
5423
6419
 
5424
6420
        t->use_all_columns();
5425
6421
 
5447
6443
              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
5448
6444
            }
5449
6445
 
5450
 
            for (uint32_t i= 0; i < t->s->fields; i++ )
 
6446
            for (uint i= 0; i < t->s->fields; i++ )
5451
6447
            {
5452
6448
              Field *f= t->field[i];
5453
 
              if ((f->type() == DRIZZLE_TYPE_BLOB) ||
5454
 
                  (f->type() == DRIZZLE_TYPE_VARCHAR))
 
6449
              if ((f->type() == MYSQL_TYPE_BLOB) ||
 
6450
                  (f->type() == MYSQL_TYPE_VARCHAR))
5455
6451
              {
5456
6452
                String tmp;
5457
6453
                f->val_str(&tmp);
5458
 
                row_crc= my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
 
6454
                row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
5459
6455
              }
5460
6456
              else
5461
6457
                row_crc= my_checksum(row_crc, f->ptr,
5464
6460
 
5465
6461
            crc+= row_crc;
5466
6462
          }
5467
 
          protocol->store((uint64_t)crc);
 
6463
          protocol->store((ulonglong)crc);
5468
6464
          t->file->ha_rnd_end();
5469
6465
        }
5470
6466
      }
5498
6494
 
5499
6495
  if (req_engine && req_engine != *new_engine)
5500
6496
  {
5501
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
6497
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
5502
6498
                       ER_WARN_USING_OTHER_HANDLER,
5503
6499
                       ER(ER_WARN_USING_OTHER_HANDLER),
5504
6500
                       ha_resolve_storage_engine_name(*new_engine),