~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

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 "mysql_priv.h"
19
 
#include <hash.h>
20
 
#include <myisam.h>
21
 
#include <my_dir.h>
22
 
#include "sql_show.h"
 
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>
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
 
                                    uint order_num, ORDER *order,
 
32
                                    uint32_t order_num, order_st *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
 
                               uint *db_options,
 
43
                               uint32_t *db_options,
44
44
                               handler *file, KEY **key_info_buffer,
45
 
                               uint *key_count, int select_field_count);
 
45
                               uint32_t *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
 
 
65
51
/*
66
52
  Translate a file name to a table name (WL #1324).
67
53
 
74
60
  RETURN
75
61
    Table name length.
76
62
*/
77
 
 
78
 
uint filename_to_tablename(const char *from, char *to, uint to_length)
 
63
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
79
64
{
80
 
  uint errors;
81
 
  uint res;
82
 
  DBUG_ENTER("filename_to_tablename");
83
 
  DBUG_PRINT("enter", ("from '%s'", from));
 
65
  uint32_t errors;
 
66
  uint32_t res;
84
67
 
85
68
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
86
69
  {
87
70
    /* Temporary table name. */
88
 
    res= (strnmov(to, from, to_length) - to);
 
71
    res= (my_stpncpy(to, from, to_length) - to);
89
72
  }
90
73
  else
91
74
  {
93
76
                    system_charset_info,  to, to_length, &errors);
94
77
    if (errors) // Old 5.0 name
95
78
    {
96
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
 
79
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NULL) -
97
80
            to);
98
 
      sql_print_error("Invalid (old?) table or database name '%s'", from);
99
 
      /*
100
 
        TODO: add a stored procedure for fix table and database names,
101
 
        and mention its name in error log.
102
 
      */
 
81
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
103
82
    }
104
83
  }
105
84
 
106
 
  DBUG_PRINT("exit", ("to '%s'", to));
107
 
  DBUG_RETURN(res);
 
85
  return(res);
108
86
}
109
87
 
110
88
 
121
99
    File name length.
122
100
*/
123
101
 
124
 
uint tablename_to_filename(const char *from, char *to, uint to_length)
 
102
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
125
103
{
126
 
  uint errors, length;
127
 
  DBUG_ENTER("tablename_to_filename");
128
 
  DBUG_PRINT("enter", ("from '%s'", from));
 
104
  uint32_t errors, length;
129
105
 
130
106
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
131
107
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
132
 
    DBUG_RETURN((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
 
108
    return((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
133
109
                                to_length-1) -
134
110
                        (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
135
111
  length= strconvert(system_charset_info, from,
140
116
    memcpy(to + length, "@@@", 4);
141
117
    length+= 3;
142
118
  }
143
 
  DBUG_PRINT("exit", ("to '%s'", to));
144
 
  DBUG_RETURN(length);
 
119
  return(length);
145
120
}
146
121
 
147
122
 
168
143
    'db' is always converted.
169
144
    'ext' is not converted.
170
145
 
171
 
    The conversion suppression is required for ALTER TABLE. This
 
146
    The conversion suppression is required for ALTER Table. This
172
147
    statement creates intermediate tables. These are regular
173
148
    (non-temporary) tables with a temporary name. Their path names must
174
149
    be derivable from the table name. So we cannot use
178
153
    path length
179
154
*/
180
155
 
181
 
uint build_table_filename(char *buff, size_t bufflen, const char *db,
182
 
                          const char *table_name, const char *ext, uint flags)
 
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)
183
158
{
184
159
  char dbbuff[FN_REFLEN];
185
160
  char tbbuff[FN_REFLEN];
186
 
  DBUG_ENTER("build_table_filename");
187
 
  DBUG_PRINT("enter", ("db: '%s'  table_name: '%s'  ext: '%s'  flags: %x",
188
 
                       db, table_name, ext, flags));
189
161
 
190
162
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
191
 
    strnmov(tbbuff, table_name, sizeof(tbbuff));
 
163
    my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
192
164
  else
193
 
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
 
165
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
194
166
 
195
 
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
 
167
  tablename_to_filename(db, dbbuff, sizeof(dbbuff));
196
168
 
197
169
  char *end = buff + bufflen;
198
170
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
199
 
  char *pos = strnmov(buff, mysql_data_home, bufflen);
 
171
  char *pos = my_stpncpy(buff, mysql_data_home, bufflen);
200
172
  int rootdir_len= strlen(FN_ROOTDIR);
201
173
  if (pos - rootdir_len >= buff &&
202
174
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
203
 
    pos= strnmov(pos, FN_ROOTDIR, end - pos);
204
 
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
 
175
    pos= my_stpncpy(pos, FN_ROOTDIR, end - pos);
 
176
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NULL);
205
177
#ifdef USE_SYMDIR
206
178
  unpack_dirname(buff, buff);
207
179
  pos= strend(buff);
208
180
#endif
209
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
 
181
  pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
210
182
 
211
 
  DBUG_PRINT("exit", ("buff: '%s'", buff));
212
 
  DBUG_RETURN(pos - buff);
 
183
  return(pos - buff);
213
184
}
214
185
 
215
186
 
231
202
    path length
232
203
*/
233
204
 
234
 
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
205
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
235
206
{
236
 
  DBUG_ENTER("build_tmptable_filename");
237
207
 
238
 
  char *p= strnmov(buff, mysql_tmpdir, bufflen);
239
 
  my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
 
208
  char *p= my_stpncpy(buff, mysql_tmpdir, bufflen);
 
209
  snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
240
210
              tmp_file_prefix, current_pid,
241
211
              thd->thread_id, thd->tmp_table++, reg_ext);
242
212
 
246
216
    my_casedn_str(files_charset_info, p);
247
217
  }
248
218
 
249
 
  uint length= unpack_filename(buff, buff);
250
 
  DBUG_PRINT("exit", ("buff: '%s'", buff));
251
 
  DBUG_RETURN(length);
252
 
}
253
 
 
254
 
/*
255
 
--------------------------------------------------------------------------
256
 
 
257
 
   MODULE: DDL log
258
 
   -----------------
259
 
 
260
 
   This module is used to ensure that we can recover from crashes that occur
261
 
   in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
262
 
   We need to ensure that both t1 and t2 are dropped and not only t1 and
263
 
   also that each table drop is entirely done and not "half-baked".
264
 
 
265
 
   To support this we create log entries for each meta-data statement in the
266
 
   ddl log while we are executing. These entries are dropped when the
267
 
   operation is completed.
268
 
 
269
 
   At recovery those entries that were not completed will be executed.
270
 
 
271
 
   There is only one ddl log in the system and it is protected by a mutex
272
 
   and there is a global struct that contains information about its current
273
 
   state.
274
 
 
275
 
   History:
276
 
   First version written in 2006 by Mikael Ronstrom
277
 
--------------------------------------------------------------------------
278
 
*/
279
 
 
280
 
 
281
 
struct st_global_ddl_log
282
 
{
283
 
  /*
284
 
    We need to adjust buffer size to be able to handle downgrades/upgrades
285
 
    where IO_SIZE has changed. We'll set the buffer size such that we can
286
 
    handle that the buffer size was upto 4 times bigger in the version
287
 
    that wrote the DDL log.
288
 
  */
289
 
  char file_entry_buf[4*IO_SIZE];
290
 
  char file_name_str[FN_REFLEN];
291
 
  char *file_name;
292
 
  DDL_LOG_MEMORY_ENTRY *first_free;
293
 
  DDL_LOG_MEMORY_ENTRY *first_used;
294
 
  uint num_entries;
295
 
  File file_id;
296
 
  uint name_len;
297
 
  uint io_size;
298
 
  bool inited;
299
 
  bool do_release;
300
 
  bool recovery_phase;
301
 
  st_global_ddl_log() : inited(false), do_release(false) {}
302
 
};
303
 
 
304
 
st_global_ddl_log global_ddl_log;
305
 
 
306
 
pthread_mutex_t LOCK_gdl;
307
 
 
308
 
#define DDL_LOG_ENTRY_TYPE_POS 0
309
 
#define DDL_LOG_ACTION_TYPE_POS 1
310
 
#define DDL_LOG_PHASE_POS 2
311
 
#define DDL_LOG_NEXT_ENTRY_POS 4
312
 
#define DDL_LOG_NAME_POS 8
313
 
 
314
 
#define DDL_LOG_NUM_ENTRY_POS 0
315
 
#define DDL_LOG_NAME_LEN_POS 4
316
 
#define DDL_LOG_IO_SIZE_POS 8
317
 
 
318
 
/*
319
 
  Read one entry from ddl log file
320
 
  SYNOPSIS
321
 
    read_ddl_log_file_entry()
322
 
    entry_no                     Entry number to read
323
 
  RETURN VALUES
324
 
    TRUE                         Error
325
 
    FALSE                        Success
326
 
*/
327
 
 
328
 
static bool read_ddl_log_file_entry(uint entry_no)
329
 
{
330
 
  bool error= FALSE;
331
 
  File file_id= global_ddl_log.file_id;
332
 
  uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
333
 
  uint io_size= global_ddl_log.io_size;
334
 
  DBUG_ENTER("read_ddl_log_file_entry");
335
 
 
336
 
  if (pread(file_id, file_entry_buf, io_size, io_size * entry_no) != io_size)
337
 
    error= TRUE;
338
 
  DBUG_RETURN(error);
339
 
}
340
 
 
341
 
 
342
 
/*
343
 
  Write one entry from ddl log file
344
 
  SYNOPSIS
345
 
    write_ddl_log_file_entry()
346
 
    entry_no                     Entry number to read
347
 
  RETURN VALUES
348
 
    TRUE                         Error
349
 
    FALSE                        Success
350
 
*/
351
 
 
352
 
static bool write_ddl_log_file_entry(uint entry_no)
353
 
{
354
 
  bool error= FALSE;
355
 
  File file_id= global_ddl_log.file_id;
356
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
357
 
  DBUG_ENTER("write_ddl_log_file_entry");
358
 
 
359
 
  if (pwrite(file_id, (uchar*)file_entry_buf,
360
 
             IO_SIZE, IO_SIZE * entry_no) != IO_SIZE)
361
 
    error= TRUE;
362
 
  DBUG_RETURN(error);
363
 
}
364
 
 
365
 
 
366
 
/*
367
 
  Write ddl log header
368
 
  SYNOPSIS
369
 
    write_ddl_log_header()
370
 
  RETURN VALUES
371
 
    TRUE                      Error
372
 
    FALSE                     Success
373
 
*/
374
 
 
375
 
static bool write_ddl_log_header()
376
 
{
377
 
  uint16 const_var;
378
 
  bool error= FALSE;
379
 
  DBUG_ENTER("write_ddl_log_header");
380
 
 
381
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
382
 
            global_ddl_log.num_entries);
383
 
  const_var= FN_LEN;
384
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
385
 
            (ulong) const_var);
386
 
  const_var= IO_SIZE;
387
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
388
 
            (ulong) const_var);
389
 
  if (write_ddl_log_file_entry(0UL))
390
 
  {
391
 
    sql_print_error("Error writing ddl log header");
392
 
    DBUG_RETURN(TRUE);
393
 
  }
394
 
  VOID(sync_ddl_log());
395
 
  DBUG_RETURN(error);
396
 
}
397
 
 
398
 
 
399
 
/*
400
 
  Create ddl log file name
401
 
  SYNOPSIS
402
 
    create_ddl_log_file_name()
403
 
    file_name                   Filename setup
404
 
  RETURN VALUES
405
 
    NONE
406
 
*/
407
 
 
408
 
static inline void create_ddl_log_file_name(char *file_name)
409
 
{
410
 
  strxmov(file_name, mysql_data_home, "/", "ddl_log.log", NullS);
411
 
}
412
 
 
413
 
 
414
 
/*
415
 
  Read header of ddl log file
416
 
  SYNOPSIS
417
 
    read_ddl_log_header()
418
 
  RETURN VALUES
419
 
    > 0                  Last entry in ddl log
420
 
    0                    No entries in ddl log
421
 
  DESCRIPTION
422
 
    When we read the ddl log header we get information about maximum sizes
423
 
    of names in the ddl log and we also get information about the number
424
 
    of entries in the ddl log.
425
 
*/
426
 
 
427
 
static uint read_ddl_log_header()
428
 
{
429
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
430
 
  char file_name[FN_REFLEN];
431
 
  uint entry_no;
432
 
  bool successful_open= FALSE;
433
 
  DBUG_ENTER("read_ddl_log_header");
434
 
 
435
 
  create_ddl_log_file_name(file_name);
436
 
  if ((global_ddl_log.file_id= my_open(file_name,
437
 
                                        O_RDWR | O_BINARY, MYF(0))) >= 0)
438
 
  {
439
 
    if (read_ddl_log_file_entry(0UL))
440
 
    {
441
 
      /* Write message into error log */
442
 
      sql_print_error("Failed to read ddl log file in recovery");
443
 
    }
444
 
    else
445
 
      successful_open= TRUE;
446
 
  }
447
 
  entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
448
 
  global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
449
 
  if (successful_open)
450
 
  {
451
 
    global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
452
 
    DBUG_ASSERT(global_ddl_log.io_size <=
453
 
                sizeof(global_ddl_log.file_entry_buf));
454
 
  }
455
 
  else
456
 
  {
457
 
    entry_no= 0;
458
 
  }
459
 
  global_ddl_log.first_free= NULL;
460
 
  global_ddl_log.first_used= NULL;
461
 
  global_ddl_log.num_entries= 0;
462
 
  VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
463
 
  global_ddl_log.do_release= true;
464
 
  DBUG_RETURN(entry_no);
465
 
}
466
 
 
467
 
 
468
 
/*
469
 
  Read a ddl log entry
470
 
  SYNOPSIS
471
 
    read_ddl_log_entry()
472
 
    read_entry               Number of entry to read
473
 
    out:entry_info           Information from entry
474
 
  RETURN VALUES
475
 
    TRUE                     Error
476
 
    FALSE                    Success
477
 
  DESCRIPTION
478
 
    Read a specified entry in the ddl log
479
 
*/
480
 
 
481
 
bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
482
 
{
483
 
  char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
484
 
  uint inx;
485
 
  uchar single_char;
486
 
  DBUG_ENTER("read_ddl_log_entry");
487
 
 
488
 
  if (read_ddl_log_file_entry(read_entry))
489
 
  {
490
 
    DBUG_RETURN(TRUE);
491
 
  }
492
 
  ddl_log_entry->entry_pos= read_entry;
493
 
  single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
494
 
  ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
495
 
  single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
496
 
  ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
497
 
  ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
498
 
  ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
499
 
  ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
500
 
  inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
501
 
  ddl_log_entry->from_name= &file_entry_buf[inx];
502
 
  inx+= global_ddl_log.name_len;
503
 
  ddl_log_entry->handler_name= &file_entry_buf[inx];
504
 
  DBUG_RETURN(FALSE);
505
 
}
506
 
 
507
 
 
508
 
/*
509
 
  Initialise ddl log
510
 
  SYNOPSIS
511
 
    init_ddl_log()
512
 
 
513
 
  DESCRIPTION
514
 
    Write the header of the ddl log file and length of names. Also set
515
 
    number of entries to zero.
516
 
 
517
 
  RETURN VALUES
518
 
    TRUE                     Error
519
 
    FALSE                    Success
520
 
*/
521
 
 
522
 
static bool init_ddl_log()
523
 
{
524
 
  char file_name[FN_REFLEN];
525
 
  DBUG_ENTER("init_ddl_log");
526
 
 
527
 
  if (global_ddl_log.inited)
528
 
    goto end;
529
 
 
530
 
  global_ddl_log.io_size= IO_SIZE;
531
 
  create_ddl_log_file_name(file_name);
532
 
  if ((global_ddl_log.file_id= my_create(file_name,
533
 
                                         CREATE_MODE,
534
 
                                         O_RDWR | O_TRUNC | O_BINARY,
535
 
                                         MYF(MY_WME))) < 0)
536
 
  {
537
 
    /* Couldn't create ddl log file, this is serious error */
538
 
    sql_print_error("Failed to open ddl log file");
539
 
    DBUG_RETURN(TRUE);
540
 
  }
541
 
  global_ddl_log.inited= TRUE;
542
 
  if (write_ddl_log_header())
543
 
  {
544
 
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
545
 
    global_ddl_log.inited= FALSE;
546
 
    DBUG_RETURN(TRUE);
547
 
  }
548
 
 
549
 
end:
550
 
  DBUG_RETURN(FALSE);
551
 
}
552
 
 
553
 
 
554
 
/*
555
 
  Execute one action in a ddl log entry
556
 
  SYNOPSIS
557
 
    execute_ddl_log_action()
558
 
    ddl_log_entry              Information in action entry to execute
559
 
  RETURN VALUES
560
 
    TRUE                       Error
561
 
    FALSE                      Success
562
 
*/
563
 
 
564
 
static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
565
 
{
566
 
  bool frm_action= FALSE;
567
 
  LEX_STRING handler_name;
568
 
  handler *file= NULL;
569
 
  MEM_ROOT mem_root;
570
 
  int error= TRUE;
571
 
  char to_path[FN_REFLEN];
572
 
  char from_path[FN_REFLEN];
573
 
  handlerton *hton;
574
 
  DBUG_ENTER("execute_ddl_log_action");
575
 
 
576
 
  if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
577
 
  {
578
 
    DBUG_RETURN(FALSE);
579
 
  }
580
 
  handler_name.str= (char*)ddl_log_entry->handler_name;
581
 
  handler_name.length= strlen(ddl_log_entry->handler_name);
582
 
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 
583
 
  if (!strcmp(ddl_log_entry->handler_name, reg_ext))
584
 
    frm_action= TRUE;
585
 
  else
586
 
  {
587
 
    plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
588
 
    if (!plugin)
589
 
    {
590
 
      my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
591
 
      goto error;
592
 
    }
593
 
    hton= plugin_data(plugin, handlerton*);
594
 
    file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
595
 
    if (!file)
596
 
    {
597
 
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
598
 
      goto error;
599
 
    }
600
 
  }
601
 
  switch (ddl_log_entry->action_type)
602
 
  {
603
 
    case DDL_LOG_REPLACE_ACTION:
604
 
    case DDL_LOG_DELETE_ACTION:
605
 
    {
606
 
      if (ddl_log_entry->phase == 0)
607
 
      {
608
 
        if (frm_action)
609
 
        {
610
 
          strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
611
 
          if ((error= my_delete(to_path, MYF(MY_WME))))
612
 
          {
613
 
            if (my_errno != ENOENT)
614
 
              break;
615
 
          }
616
 
        }
617
 
        else
618
 
        {
619
 
          if ((error= file->ha_delete_table(ddl_log_entry->name)))
620
 
          {
621
 
            if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
622
 
              break;
623
 
          }
624
 
        }
625
 
        if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
626
 
          break;
627
 
        VOID(sync_ddl_log());
628
 
        error= FALSE;
629
 
        if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
630
 
          break;
631
 
      }
632
 
      DBUG_ASSERT(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
633
 
      /*
634
 
        Fall through and perform the rename action of the replace
635
 
        action. We have already indicated the success of the delete
636
 
        action in the log entry by stepping up the phase.
637
 
      */
638
 
    }
639
 
    case DDL_LOG_RENAME_ACTION:
640
 
    {
641
 
      error= TRUE;
642
 
      if (frm_action)
643
 
      {
644
 
        strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
645
 
        strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
646
 
        if (my_rename(from_path, to_path, MYF(MY_WME)))
647
 
          break;
648
 
      }
649
 
      else
650
 
      {
651
 
        if (file->ha_rename_table(ddl_log_entry->from_name,
652
 
                                  ddl_log_entry->name))
653
 
          break;
654
 
      }
655
 
      if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
656
 
        break;
657
 
      VOID(sync_ddl_log());
658
 
      error= FALSE;
659
 
      break;
660
 
    }
661
 
    default:
662
 
      DBUG_ASSERT(0);
663
 
      break;
664
 
  }
665
 
  delete file;
666
 
error:
667
 
  free_root(&mem_root, MYF(0)); 
668
 
  DBUG_RETURN(error);
669
 
}
670
 
 
671
 
 
672
 
/*
673
 
  Get a free entry in the ddl log
674
 
  SYNOPSIS
675
 
    get_free_ddl_log_entry()
676
 
    out:active_entry                A ddl log memory entry returned
677
 
  RETURN VALUES
678
 
    TRUE                       Error
679
 
    FALSE                      Success
680
 
*/
681
 
 
682
 
static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
683
 
                                   bool *write_header)
684
 
{
685
 
  DDL_LOG_MEMORY_ENTRY *used_entry;
686
 
  DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
687
 
  DBUG_ENTER("get_free_ddl_log_entry");
688
 
 
689
 
  if (global_ddl_log.first_free == NULL)
690
 
  {
691
 
    if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
692
 
                              sizeof(DDL_LOG_MEMORY_ENTRY), MYF(MY_WME))))
693
 
    {
694
 
      sql_print_error("Failed to allocate memory for ddl log free list");
695
 
      DBUG_RETURN(TRUE);
696
 
    }
697
 
    global_ddl_log.num_entries++;
698
 
    used_entry->entry_pos= global_ddl_log.num_entries;
699
 
    *write_header= TRUE;
700
 
  }
701
 
  else
702
 
  {
703
 
    used_entry= global_ddl_log.first_free;
704
 
    global_ddl_log.first_free= used_entry->next_log_entry;
705
 
    *write_header= FALSE;
706
 
  }
707
 
  /*
708
 
    Move from free list to used list
709
 
  */
710
 
  used_entry->next_log_entry= first_used;
711
 
  used_entry->prev_log_entry= NULL;
712
 
  global_ddl_log.first_used= used_entry;
713
 
  if (first_used)
714
 
    first_used->prev_log_entry= used_entry;
715
 
 
716
 
  *active_entry= used_entry;
717
 
  DBUG_RETURN(FALSE);
718
 
}
719
 
 
720
 
 
721
 
/*
722
 
  External interface methods for the DDL log Module
723
 
  ---------------------------------------------------
724
 
*/
725
 
 
726
 
/*
727
 
  SYNOPSIS
728
 
    write_ddl_log_entry()
729
 
    ddl_log_entry         Information about log entry
730
 
    out:entry_written     Entry information written into   
731
 
 
732
 
  RETURN VALUES
733
 
    TRUE                      Error
734
 
    FALSE                     Success
735
 
 
736
 
  DESCRIPTION
737
 
    A careful write of the ddl log is performed to ensure that we can
738
 
    handle crashes occurring during CREATE and ALTER TABLE processing.
739
 
*/
740
 
 
741
 
bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
742
 
                         DDL_LOG_MEMORY_ENTRY **active_entry)
743
 
{
744
 
  bool error, write_header;
745
 
  DBUG_ENTER("write_ddl_log_entry");
746
 
 
747
 
  if (init_ddl_log())
748
 
  {
749
 
    DBUG_RETURN(TRUE);
750
 
  }
751
 
  global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
752
 
                                    (char)DDL_LOG_ENTRY_CODE;
753
 
  global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
754
 
                                    (char)ddl_log_entry->action_type;
755
 
  global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
756
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
757
 
            ddl_log_entry->next_entry);
758
 
  DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_LEN);
759
 
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
760
 
          ddl_log_entry->name, FN_LEN - 1);
761
 
  if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
762
 
      ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
763
 
  {
764
 
    DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_LEN);
765
 
    strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
766
 
          ddl_log_entry->from_name, FN_LEN - 1);
767
 
  }
768
 
  else
769
 
    global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
770
 
  DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_LEN);
771
 
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
772
 
          ddl_log_entry->handler_name, FN_LEN - 1);
773
 
  if (get_free_ddl_log_entry(active_entry, &write_header))
774
 
  {
775
 
    DBUG_RETURN(TRUE);
776
 
  }
777
 
  error= FALSE;
778
 
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
779
 
  {
780
 
    error= TRUE;
781
 
    sql_print_error("Failed to write entry_no = %u",
782
 
                    (*active_entry)->entry_pos);
783
 
  }
784
 
  if (write_header && !error)
785
 
  {
786
 
    VOID(sync_ddl_log());
787
 
    if (write_ddl_log_header())
788
 
      error= TRUE;
789
 
  }
790
 
  if (error)
791
 
    release_ddl_log_memory_entry(*active_entry);
792
 
  DBUG_RETURN(error);
793
 
}
794
 
 
795
 
 
796
 
/*
797
 
  Write final entry in the ddl log
798
 
  SYNOPSIS
799
 
    write_execute_ddl_log_entry()
800
 
    first_entry                    First entry in linked list of entries
801
 
                                   to execute, if 0 = NULL it means that
802
 
                                   the entry is removed and the entries
803
 
                                   are put into the free list.
804
 
    complete                       Flag indicating we are simply writing
805
 
                                   info about that entry has been completed
806
 
    in:out:active_entry            Entry to execute, 0 = NULL if the entry
807
 
                                   is written first time and needs to be
808
 
                                   returned. In this case the entry written
809
 
                                   is returned in this parameter
810
 
  RETURN VALUES
811
 
    TRUE                           Error
812
 
    FALSE                          Success
813
 
 
814
 
  DESCRIPTION
815
 
    This is the last write in the ddl log. The previous log entries have
816
 
    already been written but not yet synched to disk.
817
 
    We write a couple of log entries that describes action to perform.
818
 
    This entries are set-up in a linked list, however only when a first
819
 
    execute entry is put as the first entry these will be executed.
820
 
    This routine writes this first 
821
 
*/ 
822
 
 
823
 
bool write_execute_ddl_log_entry(uint first_entry,
824
 
                                 bool complete,
825
 
                                 DDL_LOG_MEMORY_ENTRY **active_entry)
826
 
{
827
 
  bool write_header= FALSE;
828
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
829
 
  DBUG_ENTER("write_execute_ddl_log_entry");
830
 
 
831
 
  if (init_ddl_log())
832
 
  {
833
 
    DBUG_RETURN(TRUE);
834
 
  }
835
 
  if (!complete)
836
 
  {
837
 
    /*
838
 
      We haven't synched the log entries yet, we synch them now before
839
 
      writing the execute entry. If complete is true we haven't written
840
 
      any log entries before, we are only here to write the execute
841
 
      entry to indicate it is done.
842
 
    */
843
 
    VOID(sync_ddl_log());
844
 
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
845
 
  }
846
 
  else
847
 
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
848
 
  file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
849
 
  file_entry_buf[DDL_LOG_PHASE_POS]= 0;
850
 
  int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
851
 
  file_entry_buf[DDL_LOG_NAME_POS]= 0;
852
 
  file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
853
 
  file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
854
 
  if (!(*active_entry))
855
 
  {
856
 
    if (get_free_ddl_log_entry(active_entry, &write_header))
857
 
    {
858
 
      DBUG_RETURN(TRUE);
859
 
    }
860
 
  }
861
 
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
862
 
  {
863
 
    sql_print_error("Error writing execute entry in ddl log");
864
 
    release_ddl_log_memory_entry(*active_entry);
865
 
    DBUG_RETURN(TRUE);
866
 
  }
867
 
  VOID(sync_ddl_log());
868
 
  if (write_header)
869
 
  {
870
 
    if (write_ddl_log_header())
871
 
    {
872
 
      release_ddl_log_memory_entry(*active_entry);
873
 
      DBUG_RETURN(TRUE);
874
 
    }
875
 
  }
876
 
  DBUG_RETURN(FALSE);
877
 
}
878
 
 
879
 
 
880
 
/*
881
 
  For complex rename operations we need to deactivate individual entries.
882
 
  SYNOPSIS
883
 
    deactivate_ddl_log_entry()
884
 
    entry_no                      Entry position of record to change
885
 
  RETURN VALUES
886
 
    TRUE                         Error
887
 
    FALSE                        Success
888
 
  DESCRIPTION
889
 
    During replace operations where we start with an existing table called
890
 
    t1 and a replacement table called t1#temp or something else and where
891
 
    we want to delete t1 and rename t1#temp to t1 this is not possible to
892
 
    do in a safe manner unless the ddl log is informed of the phases in
893
 
    the change.
894
 
 
895
 
    Delete actions are 1-phase actions that can be ignored immediately after
896
 
    being executed.
897
 
    Rename actions from x to y is also a 1-phase action since there is no
898
 
    interaction with any other handlers named x and y.
899
 
    Replace action where drop y and x -> y happens needs to be a two-phase
900
 
    action. Thus the first phase will drop y and the second phase will
901
 
    rename x -> y.
902
 
*/
903
 
 
904
 
bool deactivate_ddl_log_entry(uint entry_no)
905
 
{
906
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
907
 
  DBUG_ENTER("deactivate_ddl_log_entry");
908
 
 
909
 
  if (!read_ddl_log_file_entry(entry_no))
910
 
  {
911
 
    if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
912
 
    {
913
 
      if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
914
 
          file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
915
 
          (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
916
 
           file_entry_buf[DDL_LOG_PHASE_POS] == 1))
917
 
        file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
918
 
      else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
919
 
      {
920
 
        DBUG_ASSERT(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
921
 
        file_entry_buf[DDL_LOG_PHASE_POS]= 1;
922
 
      }
923
 
      else
924
 
      {
925
 
        DBUG_ASSERT(0);
926
 
      }
927
 
      if (write_ddl_log_file_entry(entry_no))
928
 
      {
929
 
        sql_print_error("Error in deactivating log entry. Position = %u",
930
 
                        entry_no);
931
 
        DBUG_RETURN(TRUE);
932
 
      }
933
 
    }
934
 
  }
935
 
  else
936
 
  {
937
 
    sql_print_error("Failed in reading entry before deactivating it");
938
 
    DBUG_RETURN(TRUE);
939
 
  }
940
 
  DBUG_RETURN(FALSE);
941
 
}
942
 
 
943
 
 
944
 
/*
945
 
  Sync ddl log file
946
 
  SYNOPSIS
947
 
    sync_ddl_log()
948
 
  RETURN VALUES
949
 
    TRUE                      Error
950
 
    FALSE                     Success
951
 
*/
952
 
 
953
 
bool sync_ddl_log()
954
 
{
955
 
  bool error= FALSE;
956
 
  DBUG_ENTER("sync_ddl_log");
957
 
 
958
 
  if ((!global_ddl_log.recovery_phase) &&
959
 
      init_ddl_log())
960
 
  {
961
 
    DBUG_RETURN(TRUE);
962
 
  }
963
 
  if (my_sync(global_ddl_log.file_id, MYF(0)))
964
 
  {
965
 
    /* Write to error log */
966
 
    sql_print_error("Failed to sync ddl log");
967
 
    error= TRUE;
968
 
  }
969
 
  DBUG_RETURN(error);
970
 
}
971
 
 
972
 
 
973
 
/*
974
 
  Release a log memory entry
975
 
  SYNOPSIS
976
 
    release_ddl_log_memory_entry()
977
 
    log_memory_entry                Log memory entry to release
978
 
  RETURN VALUES
979
 
    NONE
980
 
*/
981
 
 
982
 
void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
983
 
{
984
 
  DDL_LOG_MEMORY_ENTRY *first_free= global_ddl_log.first_free;
985
 
  DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
986
 
  DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
987
 
  DBUG_ENTER("release_ddl_log_memory_entry");
988
 
 
989
 
  global_ddl_log.first_free= log_entry;
990
 
  log_entry->next_log_entry= first_free;
991
 
 
992
 
  if (prev_log_entry)
993
 
    prev_log_entry->next_log_entry= next_log_entry;
994
 
  else
995
 
    global_ddl_log.first_used= next_log_entry;
996
 
  if (next_log_entry)
997
 
    next_log_entry->prev_log_entry= prev_log_entry;
998
 
  DBUG_VOID_RETURN;
999
 
}
1000
 
 
1001
 
 
1002
 
/*
1003
 
  Execute one entry in the ddl log. Executing an entry means executing
1004
 
  a linked list of actions.
1005
 
  SYNOPSIS
1006
 
    execute_ddl_log_entry()
1007
 
    first_entry                Reference to first action in entry
1008
 
  RETURN VALUES
1009
 
    TRUE                       Error
1010
 
    FALSE                      Success
1011
 
*/
1012
 
 
1013
 
bool execute_ddl_log_entry(THD *thd, uint first_entry)
1014
 
{
1015
 
  DDL_LOG_ENTRY ddl_log_entry;
1016
 
  uint read_entry= first_entry;
1017
 
  DBUG_ENTER("execute_ddl_log_entry");
1018
 
 
1019
 
  pthread_mutex_lock(&LOCK_gdl);
1020
 
  do
1021
 
  {
1022
 
    if (read_ddl_log_entry(read_entry, &ddl_log_entry))
1023
 
    {
1024
 
      /* Write to error log and continue with next log entry */
1025
 
      sql_print_error("Failed to read entry = %u from ddl log",
1026
 
                      read_entry);
1027
 
      break;
1028
 
    }
1029
 
    DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
1030
 
                ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
1031
 
 
1032
 
    if (execute_ddl_log_action(thd, &ddl_log_entry))
1033
 
    {
1034
 
      /* Write to error log and continue with next log entry */
1035
 
      sql_print_error("Failed to execute action for entry = %u from ddl log",
1036
 
                      read_entry);
1037
 
      break;
1038
 
    }
1039
 
    read_entry= ddl_log_entry.next_entry;
1040
 
  } while (read_entry);
1041
 
  pthread_mutex_unlock(&LOCK_gdl);
1042
 
  DBUG_RETURN(FALSE);
1043
 
}
1044
 
 
1045
 
 
1046
 
/*
1047
 
  Close the ddl log
1048
 
  SYNOPSIS
1049
 
    close_ddl_log()
1050
 
  RETURN VALUES
1051
 
    NONE
1052
 
*/
1053
 
 
1054
 
static void close_ddl_log()
1055
 
{
1056
 
  DBUG_ENTER("close_ddl_log");
1057
 
  if (global_ddl_log.file_id >= 0)
1058
 
  {
1059
 
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
1060
 
    global_ddl_log.file_id= (File) -1;
1061
 
  }
1062
 
  DBUG_VOID_RETURN;
1063
 
}
1064
 
 
1065
 
 
1066
 
/*
1067
 
  Execute the ddl log at recovery of MySQL Server
1068
 
  SYNOPSIS
1069
 
    execute_ddl_log_recovery()
1070
 
  RETURN VALUES
1071
 
    NONE
1072
 
*/
1073
 
 
1074
 
void execute_ddl_log_recovery()
1075
 
{
1076
 
  uint num_entries, i;
1077
 
  THD *thd;
1078
 
  DDL_LOG_ENTRY ddl_log_entry;
1079
 
  char file_name[FN_REFLEN];
1080
 
  DBUG_ENTER("execute_ddl_log_recovery");
1081
 
 
1082
 
  /*
1083
 
    Initialise global_ddl_log struct
1084
 
  */
1085
 
  bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
1086
 
  global_ddl_log.inited= FALSE;
1087
 
  global_ddl_log.recovery_phase= TRUE;
1088
 
  global_ddl_log.io_size= IO_SIZE;
1089
 
  global_ddl_log.file_id= (File) -1;
1090
 
 
1091
 
  /*
1092
 
    To be able to run this from boot, we allocate a temporary THD
1093
 
  */
1094
 
  if (!(thd=new THD))
1095
 
    DBUG_VOID_RETURN;
1096
 
  thd->thread_stack= (char*) &thd;
1097
 
  thd->store_globals();
1098
 
 
1099
 
  num_entries= read_ddl_log_header();
1100
 
  for (i= 1; i < num_entries + 1; i++)
1101
 
  {
1102
 
    if (read_ddl_log_entry(i, &ddl_log_entry))
1103
 
    {
1104
 
      sql_print_error("Failed to read entry no = %u from ddl log",
1105
 
                       i);
1106
 
      continue;
1107
 
    }
1108
 
    if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
1109
 
    {
1110
 
      if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
1111
 
      {
1112
 
        /* Real unpleasant scenario but we continue anyways.  */
1113
 
        continue;
1114
 
      }
1115
 
    }
1116
 
  }
1117
 
  close_ddl_log();
1118
 
  create_ddl_log_file_name(file_name);
1119
 
  VOID(my_delete(file_name, MYF(0)));
1120
 
  global_ddl_log.recovery_phase= FALSE;
1121
 
  delete thd;
1122
 
  /* Remember that we don't have a THD */
1123
 
  my_pthread_setspecific_ptr(THR_THD,  0);
1124
 
  DBUG_VOID_RETURN;
1125
 
}
1126
 
 
1127
 
 
1128
 
/*
1129
 
  Release all memory allocated to the ddl log
1130
 
  SYNOPSIS
1131
 
    release_ddl_log()
1132
 
  RETURN VALUES
1133
 
    NONE
1134
 
*/
1135
 
 
1136
 
void release_ddl_log()
1137
 
{
1138
 
  DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
1139
 
  DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
1140
 
  DBUG_ENTER("release_ddl_log");
1141
 
 
1142
 
  if (!global_ddl_log.do_release)
1143
 
    DBUG_VOID_RETURN;
1144
 
 
1145
 
  pthread_mutex_lock(&LOCK_gdl);
1146
 
  while (used_list)
1147
 
  {
1148
 
    DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
1149
 
    my_free(used_list, MYF(0));
1150
 
    used_list= tmp;
1151
 
  }
1152
 
  while (free_list)
1153
 
  {
1154
 
    DDL_LOG_MEMORY_ENTRY *tmp= free_list->next_log_entry;
1155
 
    my_free(free_list, MYF(0));
1156
 
    free_list= tmp;
1157
 
  }
1158
 
  close_ddl_log();
1159
 
  global_ddl_log.inited= 0;
1160
 
  pthread_mutex_unlock(&LOCK_gdl);
1161
 
  VOID(pthread_mutex_destroy(&LOCK_gdl));
1162
 
  global_ddl_log.do_release= false;
1163
 
  DBUG_VOID_RETURN;
1164
 
}
1165
 
 
1166
 
 
1167
 
/*
1168
 
---------------------------------------------------------------------------
1169
 
 
1170
 
  END MODULE DDL log
1171
 
  --------------------
1172
 
 
1173
 
---------------------------------------------------------------------------
1174
 
*/
1175
 
 
 
219
  uint32_t length= unpack_filename(buff, buff);
 
220
  return(length);
 
221
}
1176
222
 
1177
223
/*
1178
224
  SYNOPSIS
1198
244
    if (clear_error)
1199
245
      thd->clear_error();
1200
246
    thd->binlog_query(THD::STMT_QUERY_TYPE,
1201
 
                      query, query_length, FALSE, FALSE);
 
247
                      query, query_length, false, false);
1202
248
  }
1203
249
}
1204
250
 
1222
268
    not if under LOCK TABLES.
1223
269
 
1224
270
  RETURN
1225
 
    FALSE OK.  In this case ok packet is sent to user
1226
 
    TRUE  Error
 
271
    false OK.  In this case ok packet is sent to user
 
272
    true  Error
1227
273
 
1228
274
*/
1229
275
 
1230
 
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
1231
 
                    my_bool drop_temporary)
 
276
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
1232
277
{
1233
 
  bool error, need_start_waiting= FALSE;
1234
 
  DBUG_ENTER("mysql_rm_table");
 
278
  bool error, need_start_waiting= false;
1235
279
 
1236
280
  if (tables && tables->schema_table)
1237
281
  {
1238
282
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
1239
 
    DBUG_RETURN(TRUE);
 
283
    return(true);
1240
284
  }
1241
285
 
1242
286
  /* mark for close and remove all cached entries */
1245
289
  {
1246
290
    if (!thd->locked_tables &&
1247
291
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
1248
 
      DBUG_RETURN(TRUE);
 
292
      return(true);
1249
293
  }
1250
294
 
1251
295
  /*
1259
303
    start_waiting_global_read_lock(thd);
1260
304
 
1261
305
  if (error)
1262
 
    DBUG_RETURN(TRUE);
 
306
    return(true);
1263
307
  my_ok(thd);
1264
 
  DBUG_RETURN(FALSE);
 
308
  return(false);
1265
309
}
1266
310
 
1267
311
/*
1294
338
   -1   Thread was killed
1295
339
*/
1296
340
 
1297
 
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
 
341
int mysql_rm_table_part2(THD *thd, TableList *tables, bool if_exists,
1298
342
                         bool drop_temporary, bool drop_view,
1299
343
                         bool dont_log_query)
1300
344
{
1301
 
  TABLE_LIST *table;
 
345
  TableList *table;
1302
346
  char path[FN_REFLEN], *alias;
1303
 
  uint path_length;
 
347
  uint32_t path_length;
1304
348
  String wrong_tables;
1305
349
  int error= 0;
1306
350
  int non_temp_tables_count= 0;
1307
351
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
1308
352
  String built_query;
1309
 
  DBUG_ENTER("mysql_rm_table_part2");
1310
353
 
1311
354
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
1312
355
  {
1313
356
    built_query.set_charset(system_charset_info);
1314
357
    if (if_exists)
1315
 
      built_query.append("DROP TABLE IF EXISTS ");
 
358
      built_query.append("DROP Table IF EXISTS ");
1316
359
    else
1317
 
      built_query.append("DROP TABLE ");
 
360
      built_query.append("DROP Table ");
1318
361
  }
1319
362
 
1320
 
  mysql_ha_rm_tables(thd, tables, FALSE);
 
363
  mysql_ha_rm_tables(thd, tables, false);
1321
364
 
1322
365
  pthread_mutex_lock(&LOCK_open);
1323
366
 
1338
381
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
1339
382
  {
1340
383
    pthread_mutex_unlock(&LOCK_open);
1341
 
    DBUG_RETURN(1);
 
384
    return(1);
1342
385
  }
1343
386
 
1344
387
  /* Don't give warnings for not found errors, as we already generate notes */
1350
393
    handlerton *table_type;
1351
394
    enum legacy_db_type frm_db_type;
1352
395
 
1353
 
    DBUG_PRINT("table", ("table_l: '%s'.'%s'  table: 0x%lx  s: 0x%lx",
1354
 
                         table->db, table->table_name, (long) table->table,
1355
 
                         table->table ? (long) table->table->s : (long) -1));
1356
396
 
1357
397
    error= drop_temporary_table(thd, table);
1358
398
 
1362
402
      tmp_table_deleted= 1;
1363
403
      continue;
1364
404
    case -1:
1365
 
      DBUG_ASSERT(thd->in_sub_stmt);
1366
405
      error= 1;
1367
406
      goto err_with_placeholders;
1368
407
    default:
1397
436
    table_type= table->db_type;
1398
437
    if (!drop_temporary)
1399
438
    {
1400
 
      TABLE *locked_table;
 
439
      Table *locked_table;
1401
440
      abort_locked_tables(thd, db, table->table_name);
1402
441
      remove_table_from_cache(thd, db, table->table_name,
1403
442
                              RTFC_WAIT_OTHER_THREAD_FLAG |
1422
461
    }
1423
462
    if (drop_temporary ||
1424
463
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
1425
 
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
 
464
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != true)))
1426
465
    {
1427
466
      // Table was not found on disk and table can't be created from engine
1428
467
      if (if_exists)
1429
 
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
468
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1430
469
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
1431
470
                            table->table_name);
1432
471
      else
1459
498
      {
1460
499
        int new_error;
1461
500
        /* Delete the table definition file */
1462
 
        strmov(end,reg_ext);
 
501
        my_stpcpy(end,reg_ext);
1463
502
        if (!(new_error=my_delete(path,MYF(MY_WME))))
1464
503
        {
1465
504
          some_tables_deleted=1;
1474
513
        wrong_tables.append(',');
1475
514
      wrong_tables.append(String(table->table_name,system_charset_info));
1476
515
    }
1477
 
    DBUG_PRINT("table", ("table: 0x%lx  s: 0x%lx", (long) table->table,
1478
 
                         table->table ? (long) table->table->s : (long) -1));
1479
516
  }
1480
517
  /*
1481
518
    It's safe to unlock LOCK_open: we have an exclusive lock
1490
527
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
1491
528
                      wrong_tables.c_ptr());
1492
529
    else
 
530
    {
1493
531
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
 
532
    }
1494
533
    error= 1;
1495
534
  }
1496
535
 
1542
581
  }
1543
582
  pthread_mutex_lock(&LOCK_open);
1544
583
err_with_placeholders:
1545
 
  unlock_table_names(thd, tables, (TABLE_LIST*) 0);
 
584
  unlock_table_names(thd, tables, (TableList*) 0);
1546
585
  pthread_mutex_unlock(&LOCK_open);
1547
586
  thd->no_warnings_for_error= 0;
1548
 
  DBUG_RETURN(error);
 
587
  return(error);
1549
588
}
1550
589
 
1551
590
 
1565
604
*/
1566
605
 
1567
606
bool quick_rm_table(handlerton *base,const char *db,
1568
 
                    const char *table_name, uint flags)
 
607
                    const char *table_name, uint32_t flags)
1569
608
{
1570
609
  char path[FN_REFLEN];
1571
610
  bool error= 0;
1572
 
  DBUG_ENTER("quick_rm_table");
1573
611
 
1574
 
  uint path_length= build_table_filename(path, sizeof(path),
 
612
  uint32_t path_length= build_table_filename(path, sizeof(path),
1575
613
                                         db, table_name, reg_ext, flags);
1576
614
  if (my_delete(path,MYF(0)))
1577
615
    error= 1; /* purecov: inspected */
1578
616
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
1579
 
  DBUG_RETURN(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
 
617
  return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
1580
618
              error);
1581
619
}
1582
620
 
1601
639
  {
1602
640
    if (!(b_flags & HA_NOSAME))
1603
641
      return -1;
1604
 
    if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
 
642
    if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY))
1605
643
    {
1606
644
      /* Sort NOT NULL keys before other keys */
1607
 
      return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
 
645
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
1608
646
    }
1609
647
    if (a->name == primary_key_name)
1610
648
      return -1;
1647
685
 
1648
686
bool check_duplicates_in_interval(const char *set_or_name,
1649
687
                                  const char *name, TYPELIB *typelib,
1650
 
                                  CHARSET_INFO *cs, unsigned int *dup_val_count)
 
688
                                  const CHARSET_INFO * const cs, unsigned int *dup_val_count)
1651
689
{
1652
690
  TYPELIB tmp= *typelib;
1653
691
  const char **cur_value= typelib->type_names;
1688
726
  RETURN VALUES
1689
727
    void
1690
728
*/
1691
 
void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
1692
 
                                uint32 *max_length, uint32 *tot_length)
 
729
void calculate_interval_lengths(const CHARSET_INFO * const cs, TYPELIB *interval,
 
730
                                uint32_t *max_length, uint32_t *tot_length)
1693
731
{
1694
732
  const char **pos;
1695
 
  uint *len;
 
733
  uint32_t *len;
1696
734
  *max_length= *tot_length= 0;
1697
735
  for (pos= interval->type_names, len= interval->type_lengths;
1698
736
       *pos ; pos++, len++)
1699
737
  {
1700
 
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
 
738
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
1701
739
    *tot_length+= length;
1702
 
    set_if_bigger(*max_length, (uint32)length);
 
740
    set_if_bigger(*max_length, (uint32_t)length);
1703
741
  }
1704
742
}
1705
743
 
1724
762
*/
1725
763
 
1726
764
int prepare_create_field(Create_field *sql_field, 
1727
 
                         uint *blob_columns,
 
765
                         uint32_t *blob_columns,
1728
766
                         int *timestamps, int *timestamps_with_niladic,
1729
 
                         longlong table_flags)
 
767
                         int64_t table_flags __attribute__((unused)))
1730
768
{
1731
769
  unsigned int dup_val_count;
1732
 
  DBUG_ENTER("prepare_field");
1733
770
 
1734
771
  /*
1735
772
    This code came from mysql_prepare_create_table.
1736
773
    Indent preserved to make patching easier
1737
774
  */
1738
 
  DBUG_ASSERT(sql_field->charset);
 
775
  assert(sql_field->charset);
1739
776
 
1740
777
  switch (sql_field->sql_type) {
1741
 
  case MYSQL_TYPE_BLOB:
1742
 
  case MYSQL_TYPE_MEDIUM_BLOB:
1743
 
  case MYSQL_TYPE_TINY_BLOB:
1744
 
  case MYSQL_TYPE_LONG_BLOB:
 
778
  case DRIZZLE_TYPE_BLOB:
1745
779
    sql_field->pack_flag=FIELDFLAG_BLOB |
1746
780
      pack_length_to_packflag(sql_field->pack_length -
1747
781
                              portable_sizeof_char_ptr);
1751
785
    sql_field->unireg_check=Field::BLOB_FIELD;
1752
786
    (*blob_columns)++;
1753
787
    break;
1754
 
  case MYSQL_TYPE_VARCHAR:
1755
 
#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
1756
 
    if (table_flags & HA_NO_VARCHAR)
1757
 
    {
1758
 
      /* convert VARCHAR to CHAR because handler is not yet up to date */
1759
 
      sql_field->sql_type=    MYSQL_TYPE_VAR_STRING;
1760
 
      sql_field->pack_length= calc_pack_length(sql_field->sql_type,
1761
 
                                               (uint) sql_field->length);
1762
 
      if ((sql_field->length / sql_field->charset->mbmaxlen) >
1763
 
          MAX_FIELD_CHARLENGTH)
1764
 
      {
1765
 
        my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
1766
 
                        MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
1767
 
        DBUG_RETURN(1);
1768
 
      }
1769
 
    }
1770
 
#endif
1771
 
    /* fall through */
1772
 
  case MYSQL_TYPE_STRING:
 
788
  case DRIZZLE_TYPE_VARCHAR:
1773
789
    sql_field->pack_flag=0;
1774
790
    if (sql_field->charset->state & MY_CS_BINSORT)
1775
791
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1776
792
    break;
1777
 
  case MYSQL_TYPE_ENUM:
 
793
  case DRIZZLE_TYPE_ENUM:
1778
794
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
1779
795
      FIELDFLAG_INTERVAL;
1780
796
    if (sql_field->charset->state & MY_CS_BINSORT)
1783
799
    if (check_duplicates_in_interval("ENUM",sql_field->field_name,
1784
800
                                 sql_field->interval,
1785
801
                                     sql_field->charset, &dup_val_count))
1786
 
      DBUG_RETURN(1);
1787
 
    break;
1788
 
  case MYSQL_TYPE_SET:
1789
 
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
1790
 
      FIELDFLAG_BITFIELD;
1791
 
    if (sql_field->charset->state & MY_CS_BINSORT)
1792
 
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1793
 
    sql_field->unireg_check=Field::BIT_FIELD;
1794
 
    if (check_duplicates_in_interval("SET",sql_field->field_name,
1795
 
                                 sql_field->interval,
1796
 
                                     sql_field->charset, &dup_val_count))
1797
 
      DBUG_RETURN(1);
1798
 
    /* Check that count of unique members is not more then 64 */
1799
 
    if (sql_field->interval->count -  dup_val_count > sizeof(longlong)*8)
1800
 
    {
1801
 
       my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
1802
 
       DBUG_RETURN(1);
1803
 
    }
1804
 
    break;
1805
 
  case MYSQL_TYPE_DATE:                 // Rest of string types
1806
 
  case MYSQL_TYPE_NEWDATE:
1807
 
  case MYSQL_TYPE_TIME:
1808
 
  case MYSQL_TYPE_DATETIME:
1809
 
  case MYSQL_TYPE_NULL:
 
802
      return(1);
 
803
    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:
1810
808
    sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
1811
809
    break;
1812
 
  case MYSQL_TYPE_BIT:
1813
 
    /* 
1814
 
      We have sql_field->pack_flag already set here, see
1815
 
      mysql_prepare_create_table().
1816
 
    */
1817
 
    break;
1818
 
  case MYSQL_TYPE_NEWDECIMAL:
 
810
  case DRIZZLE_TYPE_NEWDECIMAL:
1819
811
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
1820
812
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
1821
813
                           FIELDFLAG_DECIMAL) |
1822
 
                          (sql_field->flags & ZEROFILL_FLAG ?
1823
 
                           FIELDFLAG_ZEROFILL : 0) |
 
814
                          (sql_field->flags & DECIMAL_FLAG ?  FIELDFLAG_DECIMAL_POSITION : 0) |
1824
815
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
1825
816
    break;
1826
 
  case MYSQL_TYPE_TIMESTAMP:
 
817
  case DRIZZLE_TYPE_TIMESTAMP:
1827
818
    /* We should replace old TIMESTAMP fields with their newer analogs */
1828
819
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
1829
820
    {
1844
835
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
1845
836
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
1846
837
                           FIELDFLAG_DECIMAL) |
1847
 
                          (sql_field->flags & ZEROFILL_FLAG ?
1848
 
                           FIELDFLAG_ZEROFILL : 0) |
1849
838
                          f_settype((uint) sql_field->sql_type) |
1850
839
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
1851
840
    break;
1852
841
  }
1853
 
  if (!(sql_field->flags & NOT_NULL_FLAG))
 
842
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
 
843
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
1854
844
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
1855
845
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
1856
846
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
1857
 
  DBUG_RETURN(0);
 
847
  return(0);
1858
848
}
1859
849
 
1860
850
/*
1879
869
    sets create_info->varchar if the table has a varchar
1880
870
 
1881
871
  RETURN VALUES
1882
 
    FALSE    OK
1883
 
    TRUE     error
 
872
    false    OK
 
873
    true     error
1884
874
*/
1885
875
 
1886
876
static int
1887
877
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
1888
878
                           Alter_info *alter_info,
1889
879
                           bool tmp_table,
1890
 
                               uint *db_options,
 
880
                               uint32_t *db_options,
1891
881
                               handler *file, KEY **key_info_buffer,
1892
 
                               uint *key_count, int select_field_count)
 
882
                               uint32_t *key_count, int select_field_count)
1893
883
{
1894
884
  const char    *key_name;
1895
885
  Create_field  *sql_field,*dup_field;
1902
892
  int           select_field_pos,auto_increment=0;
1903
893
  List_iterator<Create_field> it(alter_info->create_list);
1904
894
  List_iterator<Create_field> it2(alter_info->create_list);
1905
 
  uint total_uneven_bit_length= 0;
1906
 
  DBUG_ENTER("mysql_prepare_create_table");
 
895
  uint32_t total_uneven_bit_length= 0;
1907
896
 
1908
897
  select_field_pos= alter_info->create_list.elements - select_field_count;
1909
898
  null_fields=blob_columns=0;
1912
901
 
1913
902
  for (field_no=0; (sql_field=it++) ; field_no++)
1914
903
  {
1915
 
    CHARSET_INFO *save_cs;
 
904
    const CHARSET_INFO *save_cs;
1916
905
 
1917
906
    /*
1918
907
      Initialize length from its original value (number of characters),
1923
912
    if (!sql_field->charset)
1924
913
      sql_field->charset= create_info->default_table_charset;
1925
914
    /*
1926
 
      table_charset is set in ALTER TABLE if we want change character set
 
915
      table_charset is set in ALTER Table if we want change character set
1927
916
      for all varchar/char columns.
1928
917
      But the table charset must not affect the BLOB fields, so don't
1929
918
      allow to change my_charset_bin to somethig else.
1940
929
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
1941
930
              STRING_WITH_LEN("_bin"));
1942
931
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
1943
 
      DBUG_RETURN(TRUE);
 
932
      return(true);
1944
933
    }
1945
934
 
1946
935
    /*
1949
938
    */
1950
939
    if (sql_field->def && 
1951
940
        save_cs != sql_field->def->collation.collation &&
1952
 
        (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
1953
 
         sql_field->sql_type == MYSQL_TYPE_STRING ||
1954
 
         sql_field->sql_type == MYSQL_TYPE_SET ||
1955
 
         sql_field->sql_type == MYSQL_TYPE_ENUM))
 
941
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
1956
942
    {
1957
943
      /*
1958
944
        Starting from 5.1 we work here with a copy of Create_field
1970
956
      {
1971
957
        /* Could not convert */
1972
958
        my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1973
 
        DBUG_RETURN(TRUE);
 
959
        return(true);
1974
960
      }
1975
961
    }
1976
962
 
1977
 
    if (sql_field->sql_type == MYSQL_TYPE_SET ||
1978
 
        sql_field->sql_type == MYSQL_TYPE_ENUM)
 
963
    if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
1979
964
    {
1980
 
      uint32 dummy;
1981
 
      CHARSET_INFO *cs= sql_field->charset;
 
965
      uint32_t dummy;
 
966
      const CHARSET_INFO * const cs= sql_field->charset;
1982
967
      TYPELIB *interval= sql_field->interval;
1983
968
 
1984
969
      /*
1998
983
        List_iterator<String> int_it(sql_field->interval_list);
1999
984
        String conv, *tmp;
2000
985
        char comma_buf[4];
2001
 
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
2002
 
                                          (uchar*) comma_buf + 
 
986
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
 
987
                                          (unsigned char*) comma_buf + 
2003
988
                                          sizeof(comma_buf));
2004
 
        DBUG_ASSERT(comma_length > 0);
2005
 
        for (uint i= 0; (tmp= int_it++); i++)
 
989
        assert(comma_length > 0);
 
990
        for (uint32_t i= 0; (tmp= int_it++); i++)
2006
991
        {
2007
 
          uint lengthsp;
 
992
          uint32_t lengthsp;
2008
993
          if (String::needs_conversion(tmp->length(), tmp->charset(),
2009
994
                                       cs, &dummy))
2010
995
          {
2011
 
            uint cnv_errs;
 
996
            uint32_t cnv_errs;
2012
997
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
2013
998
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
2014
999
                                                  conv.length());
2019
1004
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
2020
1005
                                       interval->type_lengths[i]);
2021
1006
          interval->type_lengths[i]= lengthsp;
2022
 
          ((uchar *)interval->type_names[i])[lengthsp]= '\0';
2023
 
          if (sql_field->sql_type == MYSQL_TYPE_SET)
2024
 
          {
2025
 
            if (cs->coll->instr(cs, interval->type_names[i], 
2026
 
                                interval->type_lengths[i], 
2027
 
                                comma_buf, comma_length, NULL, 0))
2028
 
            {
2029
 
              my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
2030
 
              DBUG_RETURN(TRUE);
2031
 
            }
2032
 
          }
 
1007
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
2033
1008
        }
2034
1009
        sql_field->interval_list.empty(); // Don't need interval_list anymore
2035
1010
      }
2036
1011
 
2037
 
      if (sql_field->sql_type == MYSQL_TYPE_SET)
2038
 
      {
2039
 
        uint32 field_length;
2040
 
        if (sql_field->def != NULL)
2041
 
        {
2042
 
          char *not_used;
2043
 
          uint not_used2;
2044
 
          bool not_found= 0;
2045
 
          String str, *def= sql_field->def->val_str(&str);
2046
 
          if (def == NULL) /* SQL "NULL" maps to NULL */
2047
 
          {
2048
 
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
2049
 
            {
2050
 
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2051
 
              DBUG_RETURN(TRUE);
2052
 
            }
2053
 
 
2054
 
            /* else, NULL is an allowed value */
2055
 
            (void) find_set(interval, NULL, 0,
2056
 
                            cs, &not_used, &not_used2, &not_found);
2057
 
          }
2058
 
          else /* not NULL */
2059
 
          {
2060
 
            (void) find_set(interval, def->ptr(), def->length(),
2061
 
                            cs, &not_used, &not_used2, &not_found);
2062
 
          }
2063
 
 
2064
 
          if (not_found)
2065
 
          {
2066
 
            my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2067
 
            DBUG_RETURN(TRUE);
2068
 
          }
2069
 
        }
2070
 
        calculate_interval_lengths(cs, interval, &dummy, &field_length);
2071
 
        sql_field->length= field_length + (interval->count - 1);
2072
 
      }
2073
 
      else  /* MYSQL_TYPE_ENUM */
2074
 
      {
2075
 
        uint32 field_length;
2076
 
        DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
2077
 
        if (sql_field->def != NULL)
2078
 
        {
2079
 
          String str, *def= sql_field->def->val_str(&str);
2080
 
          if (def == NULL) /* SQL "NULL" maps to NULL */
2081
 
          {
2082
 
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
2083
 
            {
2084
 
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2085
 
              DBUG_RETURN(TRUE);
 
1012
      /* DRIZZLE_TYPE_ENUM */
 
1013
      {
 
1014
        uint32_t field_length;
 
1015
        assert(sql_field->sql_type == DRIZZLE_TYPE_ENUM);
 
1016
        if (sql_field->def != NULL)
 
1017
        {
 
1018
          String str, *def= sql_field->def->val_str(&str);
 
1019
          if (def == NULL) /* SQL "NULL" maps to NULL */
 
1020
          {
 
1021
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
 
1022
            {
 
1023
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
 
1024
              return(true);
2086
1025
            }
2087
1026
 
2088
1027
            /* else, the defaults yield the correct length for NULLs. */
2093
1032
            if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
2094
1033
            {
2095
1034
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2096
 
              DBUG_RETURN(TRUE);
 
1035
              return(true);
2097
1036
            }
2098
1037
          }
2099
1038
        }
2103
1042
      set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
2104
1043
    }
2105
1044
 
2106
 
    if (sql_field->sql_type == MYSQL_TYPE_BIT)
2107
 
    { 
2108
 
      sql_field->pack_flag= FIELDFLAG_NUMBER;
2109
 
      if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
2110
 
        total_uneven_bit_length+= sql_field->length & 7;
2111
 
      else
2112
 
        sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
2113
 
    }
2114
 
 
2115
1045
    sql_field->create_length_to_internal_length();
2116
1046
    if (prepare_blob_field(thd, sql_field))
2117
 
      DBUG_RETURN(TRUE);
 
1047
      return(true);
2118
1048
 
2119
1049
    if (!(sql_field->flags & NOT_NULL_FLAG))
2120
1050
      null_fields++;
2122
1052
    if (check_column_name(sql_field->field_name))
2123
1053
    {
2124
1054
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
2125
 
      DBUG_RETURN(TRUE);
 
1055
      return(true);
2126
1056
    }
2127
1057
 
2128
1058
    /* Check if we have used the same field name before */
2139
1069
        if (field_no < select_field_pos || dup_no >= select_field_pos)
2140
1070
        {
2141
1071
          my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
2142
 
          DBUG_RETURN(TRUE);
 
1072
          return(true);
2143
1073
        }
2144
1074
        else
2145
1075
        {
2164
1094
            null_fields--;
2165
1095
          sql_field->flags=             dup_field->flags;
2166
1096
          sql_field->interval=          dup_field->interval;
 
1097
          sql_field->vcol_info=         dup_field->vcol_info;
 
1098
          sql_field->is_stored=      dup_field->is_stored;
2167
1099
          it2.remove();                 // Remove first (create) definition
2168
1100
          select_field_pos--;
2169
1101
          break;
2172
1104
    }
2173
1105
    /* Don't pack rows in old tables if the user has requested this */
2174
1106
    if ((sql_field->flags & BLOB_FLAG) ||
2175
 
        (sql_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
1107
        (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
2176
1108
      (*db_options)|= HA_OPTION_PACK_RECORD;
2177
1109
    it2.rewind();
2178
1110
  }
2184
1116
  it.rewind();
2185
1117
  while ((sql_field=it++))
2186
1118
  {
2187
 
    DBUG_ASSERT(sql_field->charset != 0);
 
1119
    assert(sql_field->charset != 0);
2188
1120
 
2189
1121
    if (prepare_create_field(sql_field, &blob_columns, 
2190
1122
                             &timestamps, &timestamps_with_niladic,
2191
1123
                             file->ha_table_flags()))
2192
 
      DBUG_RETURN(TRUE);
2193
 
    if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
2194
 
      create_info->varchar= TRUE;
 
1124
      return(true);
 
1125
    if (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
 
1126
      create_info->varchar= true;
2195
1127
    sql_field->offset= record_offset;
2196
1128
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
2197
1129
      auto_increment++;
2198
 
    record_offset+= sql_field->pack_length;
 
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
    }
2199
1147
  }
2200
1148
  if (timestamps_with_niladic > 1)
2201
1149
  {
2202
1150
    my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
2203
1151
               ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
2204
 
    DBUG_RETURN(TRUE);
 
1152
    return(true);
2205
1153
  }
2206
1154
  if (auto_increment > 1)
2207
1155
  {
2208
1156
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
2209
 
    DBUG_RETURN(TRUE);
 
1157
    return(true);
2210
1158
  }
2211
1159
  if (auto_increment &&
2212
1160
      (file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
2213
1161
  {
2214
1162
    my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
2215
1163
               ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
2216
 
    DBUG_RETURN(TRUE);
 
1164
    return(true);
2217
1165
  }
2218
1166
 
2219
1167
  if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
2220
1168
  {
2221
1169
    my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
2222
1170
               MYF(0));
2223
 
    DBUG_RETURN(TRUE);
 
1171
    return(true);
2224
1172
  }
2225
1173
 
2226
1174
  /* Create keys */
2227
1175
 
2228
1176
  List_iterator<Key> key_iterator(alter_info->key_list);
2229
1177
  List_iterator<Key> key_iterator2(alter_info->key_list);
2230
 
  uint key_parts=0, fk_key_count=0;
 
1178
  uint32_t key_parts=0, fk_key_count=0;
2231
1179
  bool primary_key=0,unique_key=0;
2232
1180
  Key *key, *key2;
2233
 
  uint tmp, key_number;
 
1181
  uint32_t tmp, key_number;
2234
1182
  /* special marker for keys to be ignored */
2235
1183
  static char ignore_key[1];
2236
1184
 
2239
1187
 
2240
1188
  while ((key=key_iterator++))
2241
1189
  {
2242
 
    DBUG_PRINT("info", ("key name: '%s'  type: %d", key->name.str ? key->name.str :
2243
 
                        "(none)" , key->type));
2244
1190
    if (key->type == Key::FOREIGN_KEY)
2245
1191
    {
2246
1192
      fk_key_count++;
 
1193
      if (((Foreign_key *)key)->validate(alter_info->create_list))
 
1194
        return true;
2247
1195
      Foreign_key *fk_key= (Foreign_key*) key;
2248
1196
      if (fk_key->ref_columns.elements &&
2249
1197
          fk_key->ref_columns.elements != fk_key->columns.elements)
2252
1200
                 (fk_key->name.str ? fk_key->name.str :
2253
1201
                                     "foreign key without name"),
2254
1202
                 ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
2255
 
        DBUG_RETURN(TRUE);
 
1203
        return(true);
2256
1204
      }
2257
1205
      continue;
2258
1206
    }
2261
1209
    if (key->columns.elements > tmp)
2262
1210
    {
2263
1211
      my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
2264
 
      DBUG_RETURN(TRUE);
 
1212
      return(true);
2265
1213
    }
2266
1214
    if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))
2267
 
      DBUG_RETURN(TRUE);
 
1215
      return(true);
2268
1216
    key_iterator2.rewind ();
2269
1217
    if (key->type != Key::FOREIGN_KEY)
2270
1218
    {
2303
1251
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
2304
1252
    {
2305
1253
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
2306
 
      DBUG_RETURN(TRUE);
 
1254
      return(true);
2307
1255
    }
2308
1256
  }
2309
1257
  tmp=file->max_keys();
2310
1258
  if (*key_count > tmp)
2311
1259
  {
2312
1260
    my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
2313
 
    DBUG_RETURN(TRUE);
 
1261
    return(true);
2314
1262
  }
2315
1263
 
2316
1264
  (*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));
2317
1265
  key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
2318
1266
  if (!*key_info_buffer || ! key_part_info)
2319
 
    DBUG_RETURN(TRUE);                          // Out of memory
 
1267
    return(true);                               // Out of memory
2320
1268
 
2321
1269
  key_iterator.rewind();
2322
1270
  key_number=0;
2323
1271
  for (; (key=key_iterator++) ; key_number++)
2324
1272
  {
2325
 
    uint key_length=0;
 
1273
    uint32_t key_length=0;
2326
1274
    Key_part_spec *column;
2327
1275
 
2328
1276
    if (key->name.str == ignore_key)
2349
1297
    if (key->generated)
2350
1298
      key_info->flags|= HA_GENERATED_KEY;
2351
1299
 
2352
 
    key_info->key_parts=(uint8) key->columns.elements;
 
1300
    key_info->key_parts=(uint8_t) key->columns.elements;
2353
1301
    key_info->key_part=key_part_info;
2354
1302
    key_info->usable_key_parts= key_number;
2355
1303
    key_info->algorithm= key->key_create_info.algorithm;
2366
1314
    if (key_info->block_size)
2367
1315
      key_info->flags|= HA_USES_BLOCK_SIZE;
2368
1316
 
2369
 
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
1317
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
2370
1318
                                           key->key_create_info.comment.str,
2371
1319
                                           key->key_create_info.comment.str +
2372
1320
                                           key->key_create_info.comment.length,
2377
1325
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
2378
1326
               key->key_create_info.comment.str,"INDEX COMMENT",
2379
1327
               (uint) INDEX_COMMENT_MAXLEN);
2380
 
      DBUG_RETURN(-1);
 
1328
      return(-1);
2381
1329
    }
2382
1330
 
2383
1331
    key_info->comment.length= key->key_create_info.comment.length;
2388
1336
    }
2389
1337
 
2390
1338
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
2391
 
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
 
1339
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
2392
1340
    {
2393
 
      uint length;
 
1341
      uint32_t length;
2394
1342
      Key_part_spec *dup_column;
2395
1343
 
2396
1344
      it.rewind();
2403
1351
      if (!sql_field)
2404
1352
      {
2405
1353
        my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
2406
 
        DBUG_RETURN(TRUE);
 
1354
        return(true);
2407
1355
      }
2408
1356
      while ((dup_column= cols2++) != column)
2409
1357
      {
2413
1361
          my_printf_error(ER_DUP_FIELDNAME,
2414
1362
                          ER(ER_DUP_FIELDNAME),MYF(0),
2415
1363
                          column->field_name.str);
2416
 
          DBUG_RETURN(TRUE);
 
1364
          return(true);
2417
1365
        }
2418
1366
      }
2419
1367
      cols2.rewind();
2425
1373
          if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
2426
1374
          {
2427
1375
            my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
2428
 
            DBUG_RETURN(TRUE);
 
1376
            return(true);
2429
1377
          }
2430
1378
          if (!column->length)
2431
1379
          {
2432
1380
            my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
2433
 
            DBUG_RETURN(TRUE);
 
1381
            return(true);
2434
1382
          }
2435
1383
        }
 
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
        }
2436
1395
        if (!(sql_field->flags & NOT_NULL_FLAG))
2437
1396
        {
2438
1397
          if (key->type == Key::PRIMARY)
2448
1407
            if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
2449
1408
            {
2450
1409
              my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
2451
 
              DBUG_RETURN(TRUE);
 
1410
              return(true);
2452
1411
            }
2453
1412
          }
2454
1413
        }
2460
1419
      }
2461
1420
 
2462
1421
      key_part_info->fieldnr= field;
2463
 
      key_part_info->offset=  (uint16) sql_field->offset;
 
1422
      key_part_info->offset=  (uint16_t) sql_field->offset;
2464
1423
      key_part_info->key_type=sql_field->pack_flag;
2465
1424
      length= sql_field->key_length;
2466
1425
 
2471
1430
          if ((length=column->length) > max_key_length ||
2472
1431
              length > file->max_key_part_length())
2473
1432
          {
2474
 
            length=min(max_key_length, file->max_key_part_length());
 
1433
            length=cmin(max_key_length, file->max_key_part_length());
2475
1434
            if (key->type == Key::MULTIPLE)
2476
1435
            {
2477
1436
              /* not a critical problem */
2478
 
              char warn_buff[MYSQL_ERRMSG_SIZE];
2479
 
              my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
2480
 
                          length);
2481
 
              push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1437
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
1438
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
 
1439
                       length);
 
1440
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2482
1441
                           ER_TOO_LONG_KEY, warn_buff);
2483
1442
              /* Align key length to multibyte char boundary */
2484
1443
              length-= length % sql_field->charset->mbmaxlen;
2486
1445
            else
2487
1446
            {
2488
1447
              my_error(ER_TOO_LONG_KEY,MYF(0),length);
2489
 
              DBUG_RETURN(TRUE);
 
1448
              return(true);
2490
1449
            }
2491
1450
          }
2492
1451
        }
2498
1457
                    column->length != length)))
2499
1458
        {
2500
1459
          my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
2501
 
          DBUG_RETURN(TRUE);
 
1460
          return(true);
2502
1461
        }
2503
1462
        else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
2504
1463
          length=column->length;
2506
1465
      else if (length == 0)
2507
1466
      {
2508
1467
        my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
2509
 
          DBUG_RETURN(TRUE);
 
1468
          return(true);
2510
1469
      }
2511
1470
      if (length > file->max_key_part_length())
2512
1471
      {
2514
1473
        if (key->type == Key::MULTIPLE)
2515
1474
        {
2516
1475
          /* not a critical problem */
2517
 
          char warn_buff[MYSQL_ERRMSG_SIZE];
2518
 
          my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
2519
 
                      length);
2520
 
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1476
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
1477
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
 
1478
                   length);
 
1479
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2521
1480
                       ER_TOO_LONG_KEY, warn_buff);
2522
1481
          /* Align key length to multibyte char boundary */
2523
1482
          length-= length % sql_field->charset->mbmaxlen;
2525
1484
        else
2526
1485
        {
2527
1486
          my_error(ER_TOO_LONG_KEY,MYF(0),length);
2528
 
          DBUG_RETURN(TRUE);
 
1487
          return(true);
2529
1488
        }
2530
1489
      }
2531
 
      key_part_info->length=(uint16) length;
 
1490
      key_part_info->length=(uint16_t) length;
2532
1491
      /* Use packed keys for long strings on the first column */
2533
1492
      if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
2534
1493
          (length >= KEY_DEFAULT_PACK_LENGTH &&
2535
 
           (sql_field->sql_type == MYSQL_TYPE_STRING ||
2536
 
            sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
 
1494
           (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
2537
1495
            sql_field->pack_flag & FIELDFLAG_BLOB)))
2538
1496
      {
2539
1497
        if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
2540
 
            sql_field->sql_type == MYSQL_TYPE_VARCHAR)
 
1498
            sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
2541
1499
          key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
2542
1500
        else
2543
1501
          key_info->flags|= HA_PACK_KEY;
2558
1516
          {
2559
1517
            my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
2560
1518
                       MYF(0));
2561
 
            DBUG_RETURN(TRUE);
 
1519
            return(true);
2562
1520
          }
2563
1521
          key_name=primary_key_name;
2564
1522
          primary_key=1;
2569
1527
        if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
2570
1528
        {
2571
1529
          my_error(ER_DUP_KEYNAME, MYF(0), key_name);
2572
 
          DBUG_RETURN(TRUE);
 
1530
          return(true);
2573
1531
        }
2574
1532
        key_info->name=(char*) key_name;
2575
1533
      }
2577
1535
    if (!key_info->name || check_column_name(key_info->name))
2578
1536
    {
2579
1537
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
2580
 
      DBUG_RETURN(TRUE);
 
1538
      return(true);
2581
1539
    }
2582
1540
    if (!(key_info->flags & HA_NULL_PART_KEY))
2583
1541
      unique_key=1;
2584
 
    key_info->key_length=(uint16) key_length;
 
1542
    key_info->key_length=(uint16_t) key_length;
2585
1543
    if (key_length > max_key_length)
2586
1544
    {
2587
1545
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
2588
 
      DBUG_RETURN(TRUE);
 
1546
      return(true);
2589
1547
    }
2590
1548
    key_info++;
2591
1549
  }
2593
1551
      (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
2594
1552
  {
2595
1553
    my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
2596
 
    DBUG_RETURN(TRUE);
 
1554
    return(true);
2597
1555
  }
2598
1556
  if (auto_increment > 0)
2599
1557
  {
2600
1558
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
2601
 
    DBUG_RETURN(TRUE);
 
1559
    return(true);
2602
1560
  }
2603
1561
  /* Sort keys in optimized order */
2604
 
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
 
1562
  my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
2605
1563
           (qsort_cmp) sort_keys);
2606
1564
  create_info->null_bits= null_fields;
2607
1565
 
2613
1571
 
2614
1572
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
2615
1573
        !sql_field->def &&
2616
 
        sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
 
1574
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
2617
1575
        (sql_field->flags & NOT_NULL_FLAG) &&
2618
1576
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
2619
1577
    {
2632
1590
      */
2633
1591
 
2634
1592
      my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
2635
 
      DBUG_RETURN(TRUE);
 
1593
      return(true);
2636
1594
    }
2637
1595
  }
2638
1596
 
2639
 
  DBUG_RETURN(FALSE);
 
1597
  return(false);
2640
1598
}
2641
1599
 
2642
1600
 
2685
1643
        In this case the error is given
2686
1644
*/
2687
1645
 
2688
 
static bool prepare_blob_field(THD *thd, Create_field *sql_field)
 
1646
static bool prepare_blob_field(THD *thd __attribute__((unused)),
 
1647
                               Create_field *sql_field)
2689
1648
{
2690
 
  DBUG_ENTER("prepare_blob_field");
2691
1649
 
2692
1650
  if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
2693
1651
      !(sql_field->flags & BLOB_FLAG))
2694
1652
  {
2695
1653
    my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
2696
1654
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
2697
 
    DBUG_RETURN(1);
 
1655
    return(1);
2698
1656
  }
2699
1657
    
2700
1658
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
2701
1659
  {
2702
 
    if (sql_field->sql_type == MYSQL_TYPE_BLOB)
 
1660
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
2703
1661
    {
2704
1662
      /* The user has given a length to the blob column */
2705
1663
      sql_field->sql_type= get_blob_type_from_length(sql_field->length);
2707
1665
    }
2708
1666
    sql_field->length= 0;
2709
1667
  }
2710
 
  DBUG_RETURN(0);
 
1668
  return(0);
2711
1669
}
2712
1670
 
2713
1671
 
2728
1686
 
2729
1687
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
2730
1688
{
2731
 
  if (sql_field->sql_type == MYSQL_TYPE_SET ||
2732
 
      sql_field->sql_type == MYSQL_TYPE_ENUM)
 
1689
  if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
2733
1690
  {
2734
 
    uint32 field_length, dummy;
2735
 
    if (sql_field->sql_type == MYSQL_TYPE_SET)
2736
 
    {
2737
 
      calculate_interval_lengths(sql_field->charset,
2738
 
                                 sql_field->interval, &dummy, 
2739
 
                                 &field_length);
2740
 
      sql_field->length= field_length + 
2741
 
                         (sql_field->interval->count - 1);
2742
 
    }
2743
 
    else /* MYSQL_TYPE_ENUM */
 
1691
    uint32_t field_length, dummy;
 
1692
    /* DRIZZLE_TYPE_ENUM */
2744
1693
    {
2745
1694
      calculate_interval_lengths(sql_field->charset,
2746
1695
                                 sql_field->interval,
2750
1699
    set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
2751
1700
  }
2752
1701
 
2753
 
  if (sql_field->sql_type == MYSQL_TYPE_BIT)
2754
 
  {
2755
 
    sql_field->pack_flag= FIELDFLAG_NUMBER |
2756
 
                          FIELDFLAG_TREAT_BIT_AS_CHAR;
2757
 
  }
2758
1702
  sql_field->create_length_to_internal_length();
2759
 
  DBUG_ASSERT(sql_field->def == 0);
 
1703
  assert(sql_field->def == 0);
2760
1704
  /* Can't go wrong as sql_field->def is not defined */
2761
1705
  (void) prepare_blob_field(thd, sql_field);
2762
1706
}
2774
1718
    fields              List of fields to create
2775
1719
    keys                List of keys to create
2776
1720
    internal_tmp_table  Set to 1 if this is an internal temporary table
2777
 
                        (From ALTER TABLE)
 
1721
                        (From ALTER Table)
2778
1722
    select_field_count  
2779
1723
 
2780
1724
  DESCRIPTION
2791
1735
    and must be zero for standard create of table.
2792
1736
 
2793
1737
  RETURN VALUES
2794
 
    FALSE OK
2795
 
    TRUE  error
 
1738
    false OK
 
1739
    true  error
2796
1740
*/
2797
1741
 
2798
1742
bool mysql_create_table_no_lock(THD *thd,
2800
1744
                                HA_CREATE_INFO *create_info,
2801
1745
                                Alter_info *alter_info,
2802
1746
                                bool internal_tmp_table,
2803
 
                                uint select_field_count)
 
1747
                                uint32_t select_field_count,
 
1748
                                bool lock_open_lock)
2804
1749
{
2805
1750
  char          path[FN_REFLEN];
2806
 
  uint          path_length;
 
1751
  uint32_t          path_length;
2807
1752
  const char    *alias;
2808
1753
  uint          db_options, key_count;
2809
1754
  KEY           *key_info_buffer;
2810
1755
  handler       *file;
2811
 
  bool          error= TRUE;
2812
 
  DBUG_ENTER("mysql_create_table_no_lock");
2813
 
  DBUG_PRINT("enter", ("db: '%s'  table: '%s'  tmp: %d",
2814
 
                       db, table_name, internal_tmp_table));
2815
 
 
2816
 
 
 
1756
  bool          error= true;
2817
1757
  /* Check for duplicate fields and check type of table to create */
2818
1758
  if (!alter_info->create_list.elements)
2819
1759
  {
2820
1760
    my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
2821
1761
               MYF(0));
2822
 
    DBUG_RETURN(TRUE);
 
1762
    return(true);
2823
1763
  }
2824
1764
  if (check_engine(thd, table_name, create_info))
2825
 
    DBUG_RETURN(TRUE);
 
1765
    return(true);
2826
1766
  db_options= create_info->table_options;
2827
1767
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
2828
1768
    db_options|=HA_OPTION_PACK_RECORD;
2831
1771
                              create_info->db_type)))
2832
1772
  {
2833
1773
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
2834
 
    DBUG_RETURN(TRUE);
 
1774
    return(true);
2835
1775
  }
2836
1776
 
2837
1777
  set_table_default_charset(thd, create_info, (char*) db);
2856
1796
    if (strchr(alias, FN_DEVCHAR))
2857
1797
    {
2858
1798
      my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
2859
 
      DBUG_RETURN(TRUE);
 
1799
      return(true);
2860
1800
    }
2861
1801
#endif
2862
1802
    path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
2870
1810
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
2871
1811
    {
2872
1812
      create_info->table_existed= 1;            // Mark that table existed
2873
 
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
1813
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2874
1814
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
2875
1815
                          alias);
2876
1816
      error= 0;
2880
1820
    goto err;
2881
1821
  }
2882
1822
 
2883
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
1823
  if (lock_open_lock)
 
1824
    pthread_mutex_lock(&LOCK_open);
2884
1825
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
2885
1826
  {
2886
1827
    if (!access(path,F_OK))
2919
1860
    bool create_if_not_exists =
2920
1861
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
2921
1862
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
2922
 
    DBUG_PRINT("info", ("exists_in_engine: %u",retcode));
2923
1863
    switch (retcode)
2924
1864
    {
2925
1865
      case HA_ERR_NO_SUCH_TABLE:
2926
1866
        /* Normal case, no table exists. we can go and create it */
2927
1867
        break;
2928
1868
      case HA_ERR_TABLE_EXIST:
2929
 
        DBUG_PRINT("info", ("Table existed in handler"));
2930
1869
 
2931
1870
      if (create_if_not_exists)
2932
1871
        goto warn;
2934
1873
      goto unlock_and_end;
2935
1874
        break;
2936
1875
      default:
2937
 
        DBUG_PRINT("info", ("error: %u from storage engine", retcode));
2938
1876
        my_error(retcode, MYF(0),table_name);
2939
1877
        goto unlock_and_end;
2940
1878
    }
2941
1879
  }
2942
1880
 
2943
 
  thd_proc_info(thd, "creating table");
 
1881
  thd->set_proc_info("creating table");
2944
1882
  create_info->table_existed= 0;                // Mark that table is created
2945
1883
 
2946
1884
#ifdef HAVE_READLINK
2959
1897
#endif /* HAVE_READLINK */
2960
1898
  {
2961
1899
    if (create_info->data_file_name)
2962
 
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
 
1900
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
2963
1901
                   "DATA DIRECTORY option ignored");
2964
1902
    if (create_info->index_file_name)
2965
 
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
 
1903
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
2966
1904
                   "INDEX DIRECTORY option ignored");
2967
1905
    create_info->data_file_name= create_info->index_file_name= 0;
2968
1906
  }
2982
1920
      (void) rm_temporary_table(create_info->db_type, path, false);
2983
1921
      goto unlock_and_end;
2984
1922
    }
2985
 
    thd->thread_specific_used= TRUE;
 
1923
    thd->thread_specific_used= true;
2986
1924
  }
2987
1925
 
2988
1926
  /*
2996
1934
      (!thd->current_stmt_binlog_row_based ||
2997
1935
       (thd->current_stmt_binlog_row_based &&
2998
1936
        !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
2999
 
    write_bin_log(thd, TRUE, thd->query, thd->query_length);
3000
 
  error= FALSE;
 
1937
    write_bin_log(thd, true, thd->query, thd->query_length);
 
1938
  error= false;
3001
1939
unlock_and_end:
3002
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
1940
  if (lock_open_lock)
 
1941
    pthread_mutex_unlock(&LOCK_open);
3003
1942
 
3004
1943
err:
3005
 
  thd_proc_info(thd, "After create");
 
1944
  thd->set_proc_info("After create");
3006
1945
  delete file;
3007
 
  DBUG_RETURN(error);
 
1946
  return(error);
3008
1947
 
3009
1948
warn:
3010
 
  error= FALSE;
3011
 
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
1949
  error= false;
 
1950
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3012
1951
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
3013
1952
                      alias);
3014
1953
  create_info->table_existed= 1;                // Mark that table existed
3024
1963
                        HA_CREATE_INFO *create_info,
3025
1964
                        Alter_info *alter_info,
3026
1965
                        bool internal_tmp_table,
3027
 
                        uint select_field_count)
 
1966
                        uint32_t select_field_count)
3028
1967
{
3029
 
  TABLE *name_lock= 0;
 
1968
  Table *name_lock= 0;
3030
1969
  bool result;
3031
 
  DBUG_ENTER("mysql_create_table");
3032
1970
 
3033
1971
  /* Wait for any database locks */
3034
1972
  pthread_mutex_lock(&LOCK_lock_db);
3035
1973
  while (!thd->killed &&
3036
 
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
 
1974
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
3037
1975
  {
3038
1976
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
3039
1977
    pthread_mutex_lock(&LOCK_lock_db);
3042
1980
  if (thd->killed)
3043
1981
  {
3044
1982
    pthread_mutex_unlock(&LOCK_lock_db);
3045
 
    DBUG_RETURN(TRUE);
 
1983
    return(true);
3046
1984
  }
3047
1985
  creating_table++;
3048
1986
  pthread_mutex_unlock(&LOCK_lock_db);
3051
1989
  {
3052
1990
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
3053
1991
    {
3054
 
      result= TRUE;
 
1992
      result= true;
3055
1993
      goto unlock;
3056
1994
    }
3057
1995
    if (!name_lock)
3058
1996
    {
3059
1997
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
3060
1998
      {
3061
 
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
1999
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3062
2000
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
3063
2001
                            table_name);
3064
2002
        create_info->table_existed= 1;
3065
 
        result= FALSE;
 
2003
        result= false;
3066
2004
      }
3067
2005
      else
3068
2006
      {
3069
2007
        my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
3070
 
        result= TRUE;
 
2008
        result= true;
3071
2009
      }
3072
2010
      goto unlock;
3073
2011
    }
3076
2014
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
3077
2015
                                     alter_info,
3078
2016
                                     internal_tmp_table,
3079
 
                                     select_field_count);
 
2017
                                     select_field_count, true);
3080
2018
 
3081
2019
unlock:
3082
2020
  if (name_lock)
3083
2021
  {
3084
2022
    pthread_mutex_lock(&LOCK_open);
3085
 
    unlink_open_table(thd, name_lock, FALSE);
 
2023
    unlink_open_table(thd, name_lock, false);
3086
2024
    pthread_mutex_unlock(&LOCK_open);
3087
2025
  }
3088
2026
  pthread_mutex_lock(&LOCK_lock_db);
3089
2027
  if (!--creating_table && creating_database)
3090
2028
    pthread_cond_signal(&COND_refresh);
3091
2029
  pthread_mutex_unlock(&LOCK_lock_db);
3092
 
  DBUG_RETURN(result);
 
2030
  return(result);
3093
2031
}
3094
2032
 
3095
2033
 
3121
2059
    Only 3 chars + '\0' left, so need to limit to 2 digit
3122
2060
    This is ok as we can't have more than 100 keys anyway
3123
2061
  */
3124
 
  for (uint i=2 ; i< 100; i++)
 
2062
  for (uint32_t i=2 ; i< 100; i++)
3125
2063
  {
3126
2064
    *buff_end= '_';
3127
2065
    int10_to_str(i, buff_end+1, 10);
3154
2092
                                but only the table in the storage engine.
3155
2093
 
3156
2094
  RETURN
3157
 
    FALSE   OK
3158
 
    TRUE    Error
 
2095
    false   OK
 
2096
    true    Error
3159
2097
*/
3160
2098
 
3161
2099
bool
3162
2100
mysql_rename_table(handlerton *base, const char *old_db,
3163
2101
                   const char *old_name, const char *new_db,
3164
 
                   const char *new_name, uint flags)
 
2102
                   const char *new_name, uint32_t flags)
3165
2103
{
3166
2104
  THD *thd= current_thd;
3167
2105
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
3169
2107
  char tmp_name[NAME_LEN+1];
3170
2108
  handler *file;
3171
2109
  int error=0;
3172
 
  DBUG_ENTER("mysql_rename_table");
3173
 
  DBUG_PRINT("enter", ("old: '%s'.'%s'  new: '%s'.'%s'",
3174
 
                       old_db, old_name, new_db, new_name));
3175
2110
 
3176
2111
  file= (base == NULL ? 0 :
3177
2112
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
3189
2124
  if (lower_case_table_names == 2 && file &&
3190
2125
      !(file->ha_table_flags() & HA_FILE_BASED))
3191
2126
  {
3192
 
    strmov(tmp_name, old_name);
 
2127
    my_stpcpy(tmp_name, old_name);
3193
2128
    my_casedn_str(files_charset_info, tmp_name);
3194
2129
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
3195
2130
                         flags & FN_FROM_IS_TMP);
3196
2131
    from_base= lc_from;
3197
2132
 
3198
 
    strmov(tmp_name, new_name);
 
2133
    my_stpcpy(tmp_name, new_name);
3199
2134
    my_casedn_str(files_charset_info, tmp_name);
3200
2135
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
3201
2136
                         flags & FN_TO_IS_TMP);
3213
2148
  }
3214
2149
  delete file;
3215
2150
  if (error == HA_ERR_WRONG_COMMAND)
3216
 
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
 
2151
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
3217
2152
  else if (error)
3218
2153
    my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
3219
 
  DBUG_RETURN(error != 0);
 
2154
  return(error != 0);
3220
2155
}
3221
2156
 
3222
2157
 
3239
2174
    Win32 clients must also have a WRITE LOCK on the table !
3240
2175
*/
3241
2176
 
3242
 
void wait_while_table_is_used(THD *thd, TABLE *table,
 
2177
void wait_while_table_is_used(THD *thd, Table *table,
3243
2178
                              enum ha_extra_function function)
3244
2179
{
3245
 
  DBUG_ENTER("wait_while_table_is_used");
3246
 
  DBUG_PRINT("enter", ("table: '%s'  share: 0x%lx  db_stat: %u  version: %lu",
3247
 
                       table->s->table_name.str, (ulong) table->s,
3248
 
                       table->db_stat, table->s->version));
3249
2180
 
3250
2181
  safe_mutex_assert_owner(&LOCK_open);
3251
2182
 
3252
 
  VOID(table->file->extra(function));
 
2183
  table->file->extra(function);
3253
2184
  /* Mark all tables that are in use as 'old' */
3254
 
  mysql_lock_abort(thd, table, TRUE);   /* end threads waiting on lock */
 
2185
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
3255
2186
 
3256
2187
  /* Wait until all there are no other threads that has this table open */
3257
2188
  remove_table_from_cache(thd, table->s->db.str,
3258
2189
                          table->s->table_name.str,
3259
2190
                          RTFC_WAIT_OTHER_THREAD_FLAG);
3260
 
  DBUG_VOID_RETURN;
 
2191
  return;
3261
2192
}
3262
2193
 
3263
2194
/*
3277
2208
    Win32 clients must also have a WRITE LOCK on the table !
3278
2209
*/
3279
2210
 
3280
 
void close_cached_table(THD *thd, TABLE *table)
 
2211
void close_cached_table(THD *thd, Table *table)
3281
2212
{
3282
 
  DBUG_ENTER("close_cached_table");
3283
2213
 
3284
2214
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3285
2215
  /* Close lock if this is not got with LOCK TABLES */
3289
2219
    thd->lock=0;                        // Start locked threads
3290
2220
  }
3291
2221
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
3292
 
  unlink_open_table(thd, table, TRUE);
 
2222
  unlink_open_table(thd, table, true);
3293
2223
 
3294
2224
  /* When lock on LOCK_open is freed other threads can continue */
3295
2225
  broadcast_refresh();
3296
 
  DBUG_VOID_RETURN;
 
2226
  return;
3297
2227
}
3298
2228
 
3299
 
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
 
2229
static int send_check_errmsg(THD *thd, TableList* table,
3300
2230
                             const char* operator_name, const char* errmsg)
3301
2231
 
3302
2232
{
3313
2243
}
3314
2244
 
3315
2245
 
3316
 
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
 
2246
static int prepare_for_repair(THD *thd, TableList *table_list,
3317
2247
                              HA_CHECK_OPT *check_opt)
3318
2248
{
3319
2249
  int error= 0;
3320
 
  TABLE tmp_table, *table;
 
2250
  Table tmp_table, *table;
3321
2251
  TABLE_SHARE *share;
3322
2252
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
3323
2253
  const char **ext;
3324
2254
  struct stat stat_info;
3325
 
  DBUG_ENTER("prepare_for_repair");
3326
2255
 
3327
2256
  if (!(check_opt->sql_flags & TT_USEFRM))
3328
 
    DBUG_RETURN(0);
 
2257
    return(0);
3329
2258
 
3330
2259
  if (!(table= table_list->table))              /* if open_ltable failed */
3331
2260
  {
3332
2261
    char key[MAX_DBKEY_LENGTH];
3333
 
    uint key_length;
 
2262
    uint32_t key_length;
3334
2263
 
3335
2264
    key_length= create_table_def_key(thd, key, table_list, 0);
3336
2265
    pthread_mutex_lock(&LOCK_open);
3338
2267
                                  &error))))
3339
2268
    {
3340
2269
      pthread_mutex_unlock(&LOCK_open);
3341
 
      DBUG_RETURN(0);                           // Can't open frm file
 
2270
      return(0);                                // Can't open frm file
3342
2271
    }
3343
2272
 
3344
2273
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
3345
2274
    {
3346
2275
      release_table_share(share, RELEASE_NORMAL);
3347
2276
      pthread_mutex_unlock(&LOCK_open);
3348
 
      DBUG_RETURN(0);                           // Out of memory
 
2277
      return(0);                           // Out of memory
3349
2278
    }
3350
2279
    table= &tmp_table;
3351
2280
    pthread_mutex_unlock(&LOCK_open);
3352
2281
  }
3353
2282
 
3354
2283
  /*
3355
 
    REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
 
2284
    REPAIR Table ... USE_FRM for temporary tables makes little sense.
3356
2285
  */
3357
2286
  if (table->s->tmp_table)
3358
2287
  {
3382
2311
    goto end;                                   // No data file
3383
2312
 
3384
2313
  // Name of data file
3385
 
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
 
2314
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
3386
2315
  if (stat(from, &stat_info))
3387
2316
    goto end;                           // Can't use USE_FRM flag
3388
2317
 
3389
 
  my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
3390
 
              from, current_pid, thd->thread_id);
 
2318
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
 
2319
           from, current_pid, thd->thread_id);
3391
2320
 
3392
2321
  /* If we could open the table, close it */
3393
2322
  if (table_list->table)
3434
2363
    to finish the repair in the handler later on.
3435
2364
  */
3436
2365
  pthread_mutex_lock(&LOCK_open);
3437
 
  if (reopen_name_locked_table(thd, table_list, TRUE))
 
2366
  if (reopen_name_locked_table(thd, table_list, true))
3438
2367
  {
3439
2368
    unlock_table_name(thd, table_list);
3440
2369
    pthread_mutex_unlock(&LOCK_open);
3451
2380
    closefrm(table, 1);                         // Free allocated memory
3452
2381
    pthread_mutex_unlock(&LOCK_open);
3453
2382
  }
3454
 
  DBUG_RETURN(error);
 
2383
  return(error);
3455
2384
}
3456
2385
 
3457
2386
 
3458
2387
 
3459
2388
/*
3460
2389
  RETURN VALUES
3461
 
    FALSE Message sent to net (admin operation went ok)
3462
 
    TRUE  Message should be sent by caller 
 
2390
    false Message sent to net (admin operation went ok)
 
2391
    true  Message should be sent by caller 
3463
2392
          (admin operation or network communication failed)
3464
2393
*/
3465
 
static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
 
2394
static bool mysql_admin_table(THD* thd, TableList* tables,
3466
2395
                              HA_CHECK_OPT* check_opt,
3467
2396
                              const char *operator_name,
3468
2397
                              thr_lock_type lock_type,
3469
2398
                              bool open_for_modify,
3470
2399
                              bool no_warnings_for_error,
3471
 
                              uint extra_open_options,
3472
 
                              int (*prepare_func)(THD *, TABLE_LIST *,
 
2400
                              uint32_t extra_open_options,
 
2401
                              int (*prepare_func)(THD *, TableList *,
3473
2402
                                                  HA_CHECK_OPT *),
3474
2403
                              int (handler::*operator_func)(THD *,
3475
2404
                                                            HA_CHECK_OPT *))
3476
2405
{
3477
 
  TABLE_LIST *table;
 
2406
  TableList *table;
3478
2407
  SELECT_LEX *select= &thd->lex->select_lex;
3479
2408
  List<Item> field_list;
3480
2409
  Item *item;
3481
2410
  Protocol *protocol= thd->protocol;
3482
2411
  LEX *lex= thd->lex;
3483
2412
  int result_code= 0;
3484
 
  CHARSET_INFO *cs= system_charset_info;
3485
 
  DBUG_ENTER("mysql_admin_table");
 
2413
  const CHARSET_INFO * const cs= system_charset_info;
3486
2414
 
3487
2415
  if (end_active_trans(thd))
3488
 
    DBUG_RETURN(1);
 
2416
    return(1);
3489
2417
  field_list.push_back(item = new Item_empty_string("Table",
3490
2418
                                                    NAME_CHAR_LEN * 2,
3491
2419
                                                    cs));
3498
2426
  item->maybe_null = 1;
3499
2427
  if (protocol->send_fields(&field_list,
3500
2428
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
3501
 
    DBUG_RETURN(TRUE);
 
2429
    return(true);
3502
2430
 
3503
 
  mysql_ha_rm_tables(thd, tables, FALSE);
 
2431
  mysql_ha_rm_tables(thd, tables, false);
3504
2432
 
3505
2433
  for (table= tables; table; table= table->next_local)
3506
2434
  {
3508
2436
    char* db = table->db;
3509
2437
    bool fatal_error=0;
3510
2438
 
3511
 
    DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
3512
 
    DBUG_PRINT("admin", ("extra_open_options: %u", extra_open_options));
3513
 
    strxmov(table_name, db, ".", table->table_name, NullS);
 
2439
    strxmov(table_name, db, ".", table->table_name, NULL);
3514
2440
    thd->open_options|= extra_open_options;
3515
2441
    table->lock_type= lock_type;
3516
2442
    /* open only one table from local list of command */
3517
2443
    {
3518
 
      TABLE_LIST *save_next_global, *save_next_local;
 
2444
      TableList *save_next_global, *save_next_local;
3519
2445
      save_next_global= table->next_global;
3520
2446
      table->next_global= 0;
3521
2447
      save_next_local= table->next_local;
3522
2448
      table->next_local= 0;
3523
 
      select->table_list.first= (uchar*)table;
 
2449
      select->table_list.first= (unsigned char*)table;
3524
2450
      /*
3525
2451
        Time zone tables and SP tables can be add to lex->query_tables list,
3526
2452
        so it have to be prepared.
3531
2457
      lex->query_tables_last= &table->next_global;
3532
2458
      lex->query_tables_own_last= 0;
3533
2459
      thd->no_warnings_for_error= no_warnings_for_error;
3534
 
      table->required_type=FRMTYPE_TABLE;
3535
2460
 
3536
2461
      open_and_lock_tables(thd, table);
3537
2462
      thd->no_warnings_for_error= 0;
3539
2464
      table->next_local= save_next_local;
3540
2465
      thd->open_options&= ~extra_open_options;
3541
2466
    }
3542
 
    DBUG_PRINT("admin", ("table: 0x%lx", (long) table->table));
3543
2467
 
3544
2468
    if (prepare_func)
3545
2469
    {
3546
 
      DBUG_PRINT("admin", ("calling prepare_func"));
3547
2470
      switch ((*prepare_func)(thd, table, check_opt)) {
3548
2471
      case  1:           // error, message written to net
3549
2472
        ha_autocommit_or_rollback(thd, 1);
3550
2473
        end_trans(thd, ROLLBACK);
3551
2474
        close_thread_tables(thd);
3552
 
        DBUG_PRINT("admin", ("simple error, admin next table"));
3553
2475
        continue;
3554
2476
      case -1:           // error, message could be written to net
3555
2477
        /* purecov: begin inspected */
3556
 
        DBUG_PRINT("admin", ("severe error, stop"));
3557
2478
        goto err;
3558
2479
        /* purecov: end */
3559
2480
      default:           // should be 0 otherwise
3560
 
        DBUG_PRINT("admin", ("prepare_func succeeded"));
3561
2481
        ;
3562
2482
      }
3563
2483
    }
3564
2484
 
3565
2485
    /*
3566
 
      CHECK TABLE command is only command where VIEW allowed here and this
 
2486
      CHECK Table command is only command where VIEW allowed here and this
3567
2487
      command use only temporary teble method for VIEWs resolving => there
3568
2488
      can't be VIEW tree substitition of join view => if opening table
3569
 
      succeed then table->table will have real TABLE pointer as value (in
 
2489
      succeed then table->table will have real Table pointer as value (in
3570
2490
      case of join view substitution table->table can be 0, but here it is
3571
2491
      impossible)
3572
2492
    */
3573
2493
    if (!table->table)
3574
2494
    {
3575
 
      DBUG_PRINT("admin", ("open table failed"));
3576
2495
      if (!thd->warn_list.elements)
3577
 
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
 
2496
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
3578
2497
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
3579
2498
      goto send_result;
3580
2499
    }
3582
2501
    if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
3583
2502
    {
3584
2503
      /* purecov: begin inspected */
3585
 
      char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
3586
 
      uint length;
3587
 
      DBUG_PRINT("admin", ("sending error message"));
 
2504
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
 
2505
      uint32_t length;
3588
2506
      protocol->prepare_for_resend();
3589
2507
      protocol->store(table_name, system_charset_info);
3590
2508
      protocol->store(operator_name, system_charset_info);
3591
2509
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3592
 
      length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
3593
 
                          table_name);
 
2510
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
 
2511
                       table_name);
3594
2512
      protocol->store(buff, length, system_charset_info);
3595
2513
      ha_autocommit_or_rollback(thd, 0);
3596
2514
      end_trans(thd, COMMIT);
3597
2515
      close_thread_tables(thd);
3598
 
      lex->reset_query_tables_list(FALSE);
 
2516
      lex->reset_query_tables_list(false);
3599
2517
      table->table=0;                           // For query cache
3600
2518
      if (protocol->write())
3601
2519
        goto err;
3606
2524
    /* Close all instances of the table to allow repair to rename files */
3607
2525
    if (lock_type == TL_WRITE && table->table->s->version)
3608
2526
    {
3609
 
      DBUG_PRINT("admin", ("removing table from cache"));
3610
2527
      pthread_mutex_lock(&LOCK_open);
3611
2528
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
3612
2529
                                              "Waiting to get writelock");
3613
 
      mysql_lock_abort(thd,table->table, TRUE);
 
2530
      mysql_lock_abort(thd,table->table, true);
3614
2531
      remove_table_from_cache(thd, table->table->s->db.str,
3615
2532
                              table->table->s->table_name.str,
3616
2533
                              RTFC_WAIT_OTHER_THREAD_FLAG |
3617
2534
                              RTFC_CHECK_KILLED_FLAG);
3618
2535
      thd->exit_cond(old_message);
3619
 
      DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
3620
2536
      if (thd->killed)
3621
2537
        goto err;
3622
2538
      open_for_modify= 0;
3625
2541
    if (table->table->s->crashed && operator_func == &handler::ha_check)
3626
2542
    {
3627
2543
      /* purecov: begin inspected */
3628
 
      DBUG_PRINT("admin", ("sending crashed warning"));
3629
2544
      protocol->prepare_for_resend();
3630
2545
      protocol->store(table_name, system_charset_info);
3631
2546
      protocol->store(operator_name, system_charset_info);
3644
2559
          (table->table->file->ha_check_for_upgrade(check_opt) ==
3645
2560
           HA_ADMIN_NEEDS_ALTER))
3646
2561
      {
3647
 
        DBUG_PRINT("admin", ("recreating table"));
3648
2562
        ha_autocommit_or_rollback(thd, 1);
3649
2563
        close_thread_tables(thd);
3650
2564
        tmp_disable_binlog(thd); // binlogging is done by caller if wanted
3662
2576
      }
3663
2577
    }
3664
2578
 
3665
 
    DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
3666
2579
    result_code = (table->table->file->*operator_func)(thd, check_opt);
3667
 
    DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
3668
2580
 
3669
2581
send_result:
3670
2582
 
3671
2583
    lex->cleanup_after_one_table_open();
3672
2584
    thd->clear_error();  // these errors shouldn't get client
3673
2585
    {
3674
 
      List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
3675
 
      MYSQL_ERROR *err;
 
2586
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
2587
      DRIZZLE_ERROR *err;
3676
2588
      while ((err= it++))
3677
2589
      {
3678
2590
        protocol->prepare_for_resend();
3685
2597
        if (protocol->write())
3686
2598
          goto err;
3687
2599
      }
3688
 
      mysql_reset_errors(thd, true);
 
2600
      drizzle_reset_errors(thd, true);
3689
2601
    }
3690
2602
    protocol->prepare_for_resend();
3691
2603
    protocol->store(table_name, system_charset_info);
3693
2605
 
3694
2606
send_result_message:
3695
2607
 
3696
 
    DBUG_PRINT("info", ("result_code: %d", result_code));
3697
2608
    switch (result_code) {
3698
2609
    case HA_ADMIN_NOT_IMPLEMENTED:
3699
2610
      {
3700
2611
        char buf[ERRMSGSIZE+20];
3701
 
        uint length=my_snprintf(buf, ERRMSGSIZE,
3702
 
                                ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
 
2612
        uint32_t length=snprintf(buf, ERRMSGSIZE,
 
2613
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
3703
2614
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
3704
2615
        protocol->store(buf, length, system_charset_info);
3705
2616
      }
3708
2619
    case HA_ADMIN_NOT_BASE_TABLE:
3709
2620
      {
3710
2621
        char buf[ERRMSGSIZE+20];
3711
 
        uint length= my_snprintf(buf, ERRMSGSIZE,
3712
 
                                 ER(ER_BAD_TABLE_ERROR), table_name);
 
2622
        uint32_t length= snprintf(buf, ERRMSGSIZE,
 
2623
                              ER(ER_BAD_TABLE_ERROR), table_name);
3713
2624
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
3714
2625
        protocol->store(buf, length, system_charset_info);
3715
2626
      }
3730
2641
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
3731
2642
      protocol->store(STRING_WITH_LEN("Operation need committed state"),
3732
2643
                      system_charset_info);
3733
 
      open_for_modify= FALSE;
 
2644
      open_for_modify= false;
3734
2645
      break;
3735
2646
 
3736
2647
    case HA_ADMIN_ALREADY_DONE:
3755
2666
    {
3756
2667
      /*
3757
2668
        This is currently used only by InnoDB. ha_innobase::optimize() answers
3758
 
        "try with alter", so here we close the table, do an ALTER TABLE,
 
2669
        "try with alter", so here we close the table, do an ALTER Table,
3759
2670
        reopen the table and do ha_innobase::analyze() on it.
3760
2671
      */
3761
2672
      ha_autocommit_or_rollback(thd, 0);
3762
2673
      close_thread_tables(thd);
3763
 
      TABLE_LIST *save_next_local= table->next_local,
 
2674
      TableList *save_next_local= table->next_local,
3764
2675
                 *save_next_global= table->next_global;
3765
2676
      table->next_local= table->next_global= 0;
3766
2677
      tmp_disable_binlog(thd); // binlogging is done by caller if wanted
3784
2695
      }
3785
2696
      if (result_code) // either mysql_recreate_table or analyze failed
3786
2697
      {
3787
 
        DBUG_ASSERT(thd->is_error());
 
2698
        assert(thd->is_error());
3788
2699
        if (thd->is_error())
3789
2700
        {
3790
2701
          const char *err_msg= thd->main_da.message();
3823
2734
    case HA_ADMIN_NEEDS_ALTER:
3824
2735
    {
3825
2736
      char buf[ERRMSGSIZE];
3826
 
      uint length;
 
2737
      uint32_t length;
3827
2738
 
3828
2739
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3829
 
      length=my_snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
 
2740
      length=snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
3830
2741
      protocol->store(buf, length, system_charset_info);
3831
2742
      fatal_error=1;
3832
2743
      break;
3835
2746
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
3836
2747
      {
3837
2748
        char buf[ERRMSGSIZE+20];
3838
 
        uint length=my_snprintf(buf, ERRMSGSIZE,
3839
 
                                "Unknown - internal error %d during operation",
3840
 
                                result_code);
 
2749
        uint32_t length=snprintf(buf, ERRMSGSIZE,
 
2750
                             _("Unknown - internal error %d during operation"),
 
2751
                             result_code);
3841
2752
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3842
2753
        protocol->store(buf, length, system_charset_info);
3843
2754
        fatal_error=1;
3870
2781
  }
3871
2782
 
3872
2783
  my_eof(thd);
3873
 
  DBUG_RETURN(FALSE);
 
2784
  return(false);
3874
2785
 
3875
2786
err:
3876
2787
  ha_autocommit_or_rollback(thd, 1);
3878
2789
  close_thread_tables(thd);                     // Shouldn't be needed
3879
2790
  if (table)
3880
2791
    table->table=0;
3881
 
  DBUG_RETURN(TRUE);
 
2792
  return(true);
3882
2793
}
3883
2794
 
3884
2795
 
3885
 
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
2796
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
3886
2797
{
3887
 
  DBUG_ENTER("mysql_repair_table");
3888
 
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
 
2798
  return(mysql_admin_table(thd, tables, check_opt,
3889
2799
                                "repair", TL_WRITE, 1,
3890
2800
                                test(check_opt->sql_flags & TT_USEFRM),
3891
2801
                                HA_OPEN_FOR_REPAIR,
3894
2804
}
3895
2805
 
3896
2806
 
3897
 
bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
2807
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
3898
2808
{
3899
 
  DBUG_ENTER("mysql_optimize_table");
3900
 
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
 
2809
  return(mysql_admin_table(thd, tables, check_opt,
3901
2810
                                "optimize", TL_WRITE, 1,0,0,0,
3902
2811
                                &handler::ha_optimize));
3903
2812
}
3912
2821
    tables      Table list (one table only)
3913
2822
 
3914
2823
  RETURN VALUES
3915
 
   FALSE ok
3916
 
   TRUE  error
 
2824
   false ok
 
2825
   true  error
3917
2826
*/
3918
2827
 
3919
 
bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
 
2828
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
3920
2829
                             LEX_STRING *key_cache_name)
3921
2830
{
3922
2831
  HA_CHECK_OPT check_opt;
3923
2832
  KEY_CACHE *key_cache;
3924
 
  DBUG_ENTER("mysql_assign_to_keycache");
3925
2833
 
3926
2834
  check_opt.init();
3927
2835
  pthread_mutex_lock(&LOCK_global_system_variables);
3929
2837
  {
3930
2838
    pthread_mutex_unlock(&LOCK_global_system_variables);
3931
2839
    my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
3932
 
    DBUG_RETURN(TRUE);
 
2840
    return(true);
3933
2841
  }
3934
2842
  pthread_mutex_unlock(&LOCK_global_system_variables);
3935
2843
  check_opt.key_cache= key_cache;
3936
 
  DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
 
2844
  return(mysql_admin_table(thd, tables, &check_opt,
3937
2845
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
3938
2846
                                0, 0, &handler::assign_to_keycache));
3939
2847
}
3964
2872
    0     ok
3965
2873
*/
3966
2874
 
3967
 
int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
3968
 
                             KEY_CACHE *dst_cache)
 
2875
int reassign_keycache_tables(THD *thd __attribute__((unused)),
 
2876
                             KEY_CACHE *src_cache,
 
2877
                             KEY_CACHE *dst_cache)
3969
2878
{
3970
 
  DBUG_ENTER("reassign_keycache_tables");
3971
 
 
3972
 
  DBUG_ASSERT(src_cache != dst_cache);
3973
 
  DBUG_ASSERT(src_cache->in_init);
 
2879
  assert(src_cache != dst_cache);
 
2880
  assert(src_cache->in_init);
3974
2881
  src_cache->param_buff_size= 0;                // Free key cache
3975
2882
  ha_resize_key_cache(src_cache);
3976
2883
  ha_change_key_cache(src_cache, dst_cache);
3977
 
  DBUG_RETURN(0);
3978
 
}
3979
 
 
3980
 
 
3981
 
/*
3982
 
  Preload specified indexes for a table into key cache
3983
 
 
3984
 
  SYNOPSIS
3985
 
    mysql_preload_keys()
3986
 
    thd         Thread object
3987
 
    tables      Table list (one table only)
3988
 
 
3989
 
  RETURN VALUES
3990
 
    FALSE ok
3991
 
    TRUE  error
3992
 
*/
3993
 
 
3994
 
bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
3995
 
{
3996
 
  DBUG_ENTER("mysql_preload_keys");
3997
 
  /*
3998
 
    We cannot allow concurrent inserts. The storage engine reads
3999
 
    directly from the index file, bypassing the cache. It could read
4000
 
    outdated information if parallel inserts into cache blocks happen.
4001
 
  */
4002
 
   DBUG_RETURN(mysql_admin_table(thd, tables, 0,
4003
 
                                "preload_keys", TL_READ_NO_INSERT, 0, 0, 0, 0,
4004
 
                                &handler::preload_keys));
4005
 
}
4006
 
 
4007
 
 
 
2884
  return(0);
 
2885
}
4008
2886
 
4009
2887
/**
4010
2888
  @brief          Create frm file based on I_S table
4018
2896
    @retval       0                        success
4019
2897
    @retval       1                        error
4020
2898
*/
4021
 
 
4022
 
 
4023
 
bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
 
2899
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
4024
2900
                                  char *dst_path, HA_CREATE_INFO *create_info)
4025
2901
{
4026
2902
  HA_CREATE_INFO local_create_info;
4027
2903
  Alter_info alter_info;
4028
2904
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
4029
 
  uint keys= schema_table->table->s->keys;
4030
 
  uint db_options= 0;
4031
 
  DBUG_ENTER("mysql_create_like_schema_frm");
 
2905
  uint32_t keys= schema_table->table->s->keys;
 
2906
  uint32_t db_options= 0;
4032
2907
 
4033
 
  bzero((char*) &local_create_info, sizeof(local_create_info));
 
2908
  memset(&local_create_info, 0, sizeof(local_create_info));
4034
2909
  local_create_info.db_type= schema_table->table->s->db_type();
4035
2910
  local_create_info.row_type= schema_table->table->s->row_type;
4036
2911
  local_create_info.default_table_charset=default_charset_info;
4038
2913
  schema_table->table->use_all_columns();
4039
2914
  if (mysql_prepare_alter_table(thd, schema_table->table,
4040
2915
                                &local_create_info, &alter_info))
4041
 
    DBUG_RETURN(1);
 
2916
    return(1);
4042
2917
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
4043
2918
                                 tmp_table, &db_options,
4044
2919
                                 schema_table->table->file,
4045
2920
                                 &schema_table->table->s->key_info, &keys, 0))
4046
 
    DBUG_RETURN(1);
 
2921
    return(1);
4047
2922
  local_create_info.max_rows= 0;
4048
 
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
 
2923
  if (mysql_create_frm(thd, dst_path, NULL, NULL,
4049
2924
                       &local_create_info, alter_info.create_list,
4050
2925
                       keys, schema_table->table->s->key_info,
4051
2926
                       schema_table->table->file))
4052
 
    DBUG_RETURN(1);
4053
 
  DBUG_RETURN(0);
 
2927
    return(1);
 
2928
  return(0);
4054
2929
}
4055
2930
 
4056
2931
 
4065
2940
    create_info Create info
4066
2941
 
4067
2942
  RETURN VALUES
4068
 
    FALSE OK
4069
 
    TRUE  error
 
2943
    false OK
 
2944
    true  error
4070
2945
*/
4071
2946
 
4072
 
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
 
2947
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
4073
2948
                             HA_CREATE_INFO *create_info)
4074
2949
{
4075
 
  TABLE *name_lock= 0;
 
2950
  Table *name_lock= 0;
4076
2951
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
4077
 
  uint dst_path_length;
 
2952
  uint32_t dst_path_length;
4078
2953
  char *db= table->db;
4079
2954
  char *table_name= table->table_name;
4080
2955
  int  err;
4081
 
  bool res= TRUE;
4082
 
  uint not_used;
4083
 
  DBUG_ENTER("mysql_create_like_table");
4084
 
 
4085
 
 
4086
 
  /* CREATE TABLE ... LIKE is not allowed for views. */
4087
 
  src_table->required_type= FRMTYPE_TABLE;
 
2956
  bool res= true;
 
2957
  uint32_t not_used;
4088
2958
 
4089
2959
  /*
4090
2960
    By opening source table we guarantee that it exists and no concurrent
4096
2966
    operations which matter.
4097
2967
  */
4098
2968
  if (open_tables(thd, &src_table, &not_used, 0))
4099
 
    DBUG_RETURN(TRUE);
4100
 
 
4101
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
4102
 
 
4103
 
  DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
 
2969
    return(true);
 
2970
 
 
2971
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
4104
2972
 
4105
2973
  /* 
4106
2974
    Check that destination tables does not exist. Note that its name
4125
2993
      goto table_exists;
4126
2994
  }
4127
2995
 
4128
 
  DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
4129
 
 
4130
2996
  /*
4131
2997
    Create a new table by copying from source table
4132
2998
 
4140
3006
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
4141
3007
    during the call to ha_create_table(). See bug #28614 for more info.
4142
3008
  */
4143
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
3009
  pthread_mutex_lock(&LOCK_open);
4144
3010
  if (src_table->schema_table)
4145
3011
  {
4146
3012
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
4147
3013
    {
4148
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
3014
      pthread_mutex_unlock(&LOCK_open);
4149
3015
      goto err;
4150
3016
    }
4151
3017
  }
4155
3021
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
4156
3022
    else
4157
3023
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
4158
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3024
    pthread_mutex_unlock(&LOCK_open);
4159
3025
    goto err;
4160
3026
  }
4161
3027
 
4164
3030
    creation, instead create the table directly (for both normal
4165
3031
    and temporary tables).
4166
3032
  */
4167
 
  DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
4168
 
 
4169
3033
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
4170
3034
  if (thd->variables.keep_files_on_create)
4171
3035
    create_info->options|= HA_CREATE_KEEP_FILES;
4172
3036
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
4173
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3037
  pthread_mutex_unlock(&LOCK_open);
4174
3038
 
4175
3039
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
4176
3040
  {
4189
3053
    goto err;       /* purecov: inspected */
4190
3054
  }
4191
3055
 
4192
 
  DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
4193
 
 
4194
3056
  /*
4195
3057
    We have to write the query before we unlock the tables.
4196
3058
  */
4227
3089
          of this function.
4228
3090
        */
4229
3091
        table->table= name_lock;
4230
 
        VOID(pthread_mutex_lock(&LOCK_open));
4231
 
        if (reopen_name_locked_table(thd, table, FALSE))
 
3092
        pthread_mutex_lock(&LOCK_open);
 
3093
        if (reopen_name_locked_table(thd, table, false))
4232
3094
        {
4233
 
          VOID(pthread_mutex_unlock(&LOCK_open));
 
3095
          pthread_mutex_unlock(&LOCK_open);
4234
3096
          goto err;
4235
3097
        }
4236
 
        VOID(pthread_mutex_unlock(&LOCK_open));
 
3098
        pthread_mutex_unlock(&LOCK_open);
4237
3099
 
4238
 
        IF_DBUG(int result=) store_create_info(thd, table, &query,
 
3100
        int result= store_create_info(thd, table, &query,
4239
3101
                                               create_info);
4240
3102
 
4241
 
        DBUG_ASSERT(result == 0); // store_create_info() always return 0
4242
 
        write_bin_log(thd, TRUE, query.ptr(), query.length());
 
3103
        assert(result == 0); // store_create_info() always return 0
 
3104
        write_bin_log(thd, true, query.ptr(), query.length());
4243
3105
      }
4244
3106
      else                                      // Case 1
4245
 
        write_bin_log(thd, TRUE, thd->query, thd->query_length);
 
3107
        write_bin_log(thd, true, thd->query, thd->query_length);
4246
3108
    }
4247
3109
    /*
4248
3110
      Case 3 and 4 does nothing under RBR
4249
3111
    */
4250
3112
  }
4251
3113
  else
4252
 
    write_bin_log(thd, TRUE, thd->query, thd->query_length);
 
3114
    write_bin_log(thd, true, thd->query, thd->query_length);
4253
3115
 
4254
 
  res= FALSE;
 
3116
  res= false;
4255
3117
  goto err;
4256
3118
 
4257
3119
table_exists:
4258
3120
  if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
4259
3121
  {
4260
 
    char warn_buff[MYSQL_ERRMSG_SIZE];
4261
 
    my_snprintf(warn_buff, sizeof(warn_buff),
4262
 
                ER(ER_TABLE_EXISTS_ERROR), table_name);
4263
 
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
3122
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
3123
    snprintf(warn_buff, sizeof(warn_buff),
 
3124
             ER(ER_TABLE_EXISTS_ERROR), table_name);
 
3125
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4264
3126
                 ER_TABLE_EXISTS_ERROR,warn_buff);
4265
 
    res= FALSE;
 
3127
    res= false;
4266
3128
  }
4267
3129
  else
4268
3130
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
4271
3133
  if (name_lock)
4272
3134
  {
4273
3135
    pthread_mutex_lock(&LOCK_open);
4274
 
    unlink_open_table(thd, name_lock, FALSE);
 
3136
    unlink_open_table(thd, name_lock, false);
4275
3137
    pthread_mutex_unlock(&LOCK_open);
4276
3138
  }
4277
 
  DBUG_RETURN(res);
 
3139
  return(res);
4278
3140
}
4279
3141
 
4280
3142
 
4281
 
bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
3143
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
4282
3144
{
4283
3145
  thr_lock_type lock_type = TL_READ_NO_INSERT;
4284
3146
 
4285
 
  DBUG_ENTER("mysql_analyze_table");
4286
 
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
 
3147
  return(mysql_admin_table(thd, tables, check_opt,
4287
3148
                                "analyze", lock_type, 1, 0, 0, 0,
4288
3149
                                &handler::ha_analyze));
4289
3150
}
4290
3151
 
4291
3152
 
4292
 
bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
 
3153
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
4293
3154
{
4294
3155
  thr_lock_type lock_type = TL_READ_NO_INSERT;
4295
3156
 
4296
 
  DBUG_ENTER("mysql_check_table");
4297
 
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
 
3157
  return(mysql_admin_table(thd, tables, check_opt,
4298
3158
                                "check", lock_type,
4299
3159
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
4300
3160
                                &handler::ha_check));
4304
3164
/* table_list should contain just one table */
4305
3165
static int
4306
3166
mysql_discard_or_import_tablespace(THD *thd,
4307
 
                                   TABLE_LIST *table_list,
 
3167
                                   TableList *table_list,
4308
3168
                                   enum tablespace_op_type tablespace_op)
4309
3169
{
4310
 
  TABLE *table;
4311
 
  my_bool discard;
 
3170
  Table *table;
 
3171
  bool discard;
4312
3172
  int error;
4313
 
  DBUG_ENTER("mysql_discard_or_import_tablespace");
4314
3173
 
4315
3174
  /*
4316
3175
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
4317
 
    ALTER TABLE
 
3176
    ALTER Table
4318
3177
  */
4319
3178
 
4320
 
  thd_proc_info(thd, "discard_or_import_tablespace");
 
3179
  thd->set_proc_info("discard_or_import_tablespace");
4321
3180
 
4322
3181
  discard= test(tablespace_op == DISCARD_TABLESPACE);
4323
3182
 
4325
3184
   We set this flag so that ha_innobase::open and ::external_lock() do
4326
3185
   not complain when we lock the table
4327
3186
 */
4328
 
  thd->tablespace_op= TRUE;
 
3187
  thd->tablespace_op= true;
4329
3188
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
4330
3189
  {
4331
 
    thd->tablespace_op=FALSE;
4332
 
    DBUG_RETURN(-1);
 
3190
    thd->tablespace_op=false;
 
3191
    return(-1);
4333
3192
  }
4334
3193
 
4335
3194
  error= table->file->ha_discard_or_import_tablespace(discard);
4336
3195
 
4337
 
  thd_proc_info(thd, "end");
 
3196
  thd->set_proc_info("end");
4338
3197
 
4339
3198
  if (error)
4340
3199
    goto err;
4341
3200
 
4342
 
  /* The ALTER TABLE is always in its own transaction */
 
3201
  /* The ALTER Table is always in its own transaction */
4343
3202
  error = ha_autocommit_or_rollback(thd, 0);
4344
3203
  if (end_active_trans(thd))
4345
3204
    error=1;
4346
3205
  if (error)
4347
3206
    goto err;
4348
 
  write_bin_log(thd, FALSE, thd->query, thd->query_length);
 
3207
  write_bin_log(thd, false, thd->query, thd->query_length);
4349
3208
 
4350
3209
err:
4351
3210
  ha_autocommit_or_rollback(thd, error);
4352
 
  thd->tablespace_op=FALSE;
 
3211
  thd->tablespace_op=false;
4353
3212
  
4354
3213
  if (error == 0)
4355
3214
  {
4356
3215
    my_ok(thd);
4357
 
    DBUG_RETURN(0);
 
3216
    return(0);
4358
3217
  }
4359
3218
 
4360
3219
  table->file->print_error(error, MYF(0));
4361
3220
    
4362
 
  DBUG_RETURN(-1);
 
3221
  return(-1);
4363
3222
}
4364
3223
 
4365
3224
/**
4368
3227
 
4369
3228
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
4370
3229
{
4371
 
  uint flags= alter_info->flags;
 
3230
  uint32_t flags= alter_info->flags;
4372
3231
 
4373
3232
  if (ALTER_ADD_COLUMN & flags)
4374
3233
    *alter_flags|= HA_ADD_COLUMN;
4413
3272
   table has in arguments create_list, key_list and create_info.
4414
3273
 
4415
3274
   By comparing the changes between the original and new table
4416
 
   we can determine how much it has changed after ALTER TABLE
 
3275
   we can determine how much it has changed after ALTER Table
4417
3276
   and whether we need to make a copy of the table, or just change
4418
3277
   the .frm file.
4419
3278
 
4424
3283
   table->key_info or key_info_buffer respectively for the indexes
4425
3284
   that need to be dropped and/or (re-)created.
4426
3285
 
4427
 
   @retval TRUE  error
4428
 
   @retval FALSE success
 
3286
   @retval true  error
 
3287
   @retval false success
4429
3288
*/
4430
3289
 
4431
3290
static
4432
3291
bool
4433
3292
compare_tables(THD *thd,
4434
 
               TABLE *table,
 
3293
               Table *table,
4435
3294
               Alter_info *alter_info,
4436
3295
                           HA_CREATE_INFO *create_info,
4437
 
               uint order_num,
 
3296
               uint32_t order_num,
4438
3297
               HA_ALTER_FLAGS *alter_flags,
4439
3298
               HA_ALTER_INFO *ha_alter_info,
4440
 
               uint *table_changes)
 
3299
               uint32_t *table_changes)
4441
3300
{
4442
3301
  Field **f_ptr, *field;
4443
 
  uint table_changes_local= 0;
 
3302
  uint32_t table_changes_local= 0;
4444
3303
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
4445
3304
  Create_field *new_field;
4446
3305
  KEY_PART_INFO *key_part;
4450
3309
    create_info->varchar will be reset in mysql_prepare_create_table.
4451
3310
  */
4452
3311
  bool varchar= create_info->varchar;
4453
 
  DBUG_ENTER("compare_tables");
4454
3312
 
4455
3313
  {
4456
3314
    /*
4465
3323
      like to keep compare_tables() idempotent (not altering any
4466
3324
      of the arguments) we create a copy of alter_info here and
4467
3325
      pass it to mysql_prepare_create_table, then use the result
4468
 
      to evaluate possibility of fast ALTER TABLE, and then
 
3326
      to evaluate possibility of fast ALTER Table, and then
4469
3327
      destroy the copy.
4470
3328
    */
4471
3329
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
4472
3330
    THD *thd= table->in_use;
4473
 
    uint db_options= 0; /* not used */
 
3331
    uint32_t db_options= 0; /* not used */
4474
3332
    /* Create the prepared information. */
4475
3333
    if (mysql_prepare_create_table(thd, create_info,
4476
3334
                                   &tmp_alter_info,
4480
3338
                                   &ha_alter_info->key_info_buffer,
4481
3339
                                   &ha_alter_info->key_count,
4482
3340
                                   /* select_field_count */ 0))
4483
 
      DBUG_RETURN(TRUE);
 
3341
      return(true);
4484
3342
    /* Allocate result buffers. */
4485
3343
    if (! (ha_alter_info->index_drop_buffer=
4486
3344
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
4487
3345
        ! (ha_alter_info->index_add_buffer=
4488
3346
           (uint*) thd->alloc(sizeof(uint) *
4489
3347
                              tmp_alter_info.key_list.elements)))
4490
 
      DBUG_RETURN(TRUE);
 
3348
      return(true);
4491
3349
  }
4492
3350
  /*
4493
3351
    First we setup ha_alter_flags based on what was detected
4495
3353
  */
4496
3354
  setup_ha_alter_flags(alter_info, alter_flags);
4497
3355
 
4498
 
#ifndef DBUG_OFF
4499
 
  {
4500
 
    char dbug_string[HA_MAX_ALTER_FLAGS+1];
4501
 
    alter_flags->print(dbug_string);
4502
 
    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
4503
 
  }
4504
 
#endif
4505
3356
 
4506
3357
  /*
4507
3358
    Some very basic checks. If number of fields changes, or the
4508
 
    handler, we need to run full ALTER TABLE. In the future
 
3359
    handler, we need to run full ALTER Table. In the future
4509
3360
    new fields can be added and old dropped without copy, but
4510
3361
    not yet.
4511
3362
 
4512
 
    Test also that engine was not given during ALTER TABLE, or
 
3363
    Test also that engine was not given during ALTER Table, or
4513
3364
    we are force to run regular alter table (copy).
4514
 
    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
 
3365
    E.g. ALTER Table tbl_name ENGINE=MyISAM.
4515
3366
 
4516
3367
    For the following ones we also want to run regular alter table:
4517
 
    ALTER TABLE tbl_name ORDER BY ..
4518
 
    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
 
3368
    ALTER Table tbl_name order_st BY ..
 
3369
    ALTER Table tbl_name CONVERT TO CHARACTER SET ..
4519
3370
 
4520
3371
    At the moment we can't handle altering temporary tables without a copy.
4521
 
    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
 
3372
    We also test if OPTIMIZE Table was given and was mapped to alter table.
4522
3373
    In that case we always do full copy.
4523
3374
 
4524
3375
    There was a bug prior to mysql-4.0.25. Number of null fields was
4580
3431
    /* Don't pack rows in old tables if the user has requested this. */
4581
3432
    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
4582
3433
        (new_field->flags & BLOB_FLAG) ||
4583
 
        (new_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
3434
        (new_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
4584
3435
      create_info->table_options|= HA_OPTION_PACK_RECORD;
4585
3436
 
4586
3437
    /* Check how fields have been modified */
4590
3441
      if (!(table_changes_local= field->is_equal(new_field)))
4591
3442
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
4592
3443
 
 
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
 
4593
3452
      /* Check if field was renamed */
4594
3453
      field->flags&= ~FIELD_IS_RENAMED;
4595
3454
      if (my_strcasecmp(system_charset_info,
4627
3486
  KEY *new_key_end=
4628
3487
       ha_alter_info->key_info_buffer + ha_alter_info->key_count;
4629
3488
 
4630
 
  DBUG_PRINT("info", ("index count old: %d  new: %d",
4631
 
                      table->s->keys, ha_alter_info->key_count));
4632
3489
  /*
4633
3490
    Step through all keys of the old table and search matching new keys.
4634
3491
  */
4666
3523
      else
4667
3524
        *alter_flags|= HA_DROP_INDEX;
4668
3525
      *table_changes= IS_EQUAL_NO;
4669
 
      DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
4670
3526
      continue;
4671
3527
    }
4672
3528
 
4739
3595
        field->flags|= FIELD_IN_ADD_INDEX;
4740
3596
    }
4741
3597
    *table_changes= IS_EQUAL_NO;
4742
 
    DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
4743
3598
  }
4744
3599
  /*end of for (; table_key < table_key_end;) */
4745
3600
 
4782
3637
      else
4783
3638
        *alter_flags|= HA_ADD_INDEX;
4784
3639
      *table_changes= IS_EQUAL_NO;
4785
 
      DBUG_PRINT("info", ("index added: '%s'", new_key->name));
4786
3640
    }
4787
3641
  }
4788
 
#ifndef DBUG_OFF
4789
 
  {
4790
 
    char dbug_string[HA_MAX_ALTER_FLAGS+1];
4791
 
    alter_flags->print(dbug_string);
4792
 
    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
4793
 
  }
4794
 
#endif
4795
3642
 
4796
 
  DBUG_RETURN(FALSE);
 
3643
  return(false);
4797
3644
}
4798
3645
 
4799
3646
 
4800
3647
/*
4801
 
  Manages enabling/disabling of indexes for ALTER TABLE
 
3648
  Manages enabling/disabling of indexes for ALTER Table
4802
3649
 
4803
3650
  SYNOPSIS
4804
3651
    alter_table_manage_keys()
4808
3655
      keys_onoff             ENABLE | DISABLE | LEAVE_AS_IS
4809
3656
 
4810
3657
  RETURN VALUES
4811
 
    FALSE  OK
4812
 
    TRUE   Error
 
3658
    false  OK
 
3659
    true   Error
4813
3660
*/
4814
3661
 
4815
3662
static
4816
 
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
 
3663
bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
4817
3664
                             enum enum_enable_or_disable keys_onoff)
4818
3665
{
4819
3666
  int error= 0;
4820
 
  DBUG_ENTER("alter_table_manage_keys");
4821
 
  DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
4822
 
             table, indexes_were_disabled, keys_onoff));
4823
 
 
4824
3667
  switch (keys_onoff) {
4825
3668
  case ENABLE:
4826
3669
    error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4835
3678
 
4836
3679
  if (error == HA_ERR_WRONG_COMMAND)
4837
3680
  {
4838
 
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
3681
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4839
3682
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4840
3683
                        table->s->table_name.str);
4841
3684
    error= 0;
4842
3685
  } else if (error)
4843
3686
    table->file->print_error(error, MYF(0));
4844
3687
 
4845
 
  DBUG_RETURN(error);
 
3688
  return(error);
4846
3689
}
4847
3690
 
4848
3691
int create_temporary_table(THD *thd,
4849
 
                           TABLE *table,
 
3692
                           Table *table,
4850
3693
                           char *new_db,
4851
3694
                           char *tmp_name,
4852
3695
                           HA_CREATE_INFO *create_info,
4856
3699
  int error;
4857
3700
  char index_file[FN_REFLEN], data_file[FN_REFLEN];
4858
3701
  handlerton *old_db_type, *new_db_type;
4859
 
  DBUG_ENTER("create_temporary_table");
4860
3702
  old_db_type= table->s->db_type();
4861
3703
  new_db_type= create_info->db_type;
4862
3704
  /*
4888
3730
    if (create_info->index_file_name)
4889
3731
    {
4890
3732
      /* Fix index_file_name to have 'tmp_name' as basename */
4891
 
      strmov(index_file, tmp_name);
 
3733
      my_stpcpy(index_file, tmp_name);
4892
3734
      create_info->index_file_name=fn_same(index_file,
4893
3735
                                           create_info->index_file_name,
4894
3736
                                           1);
4896
3738
    if (create_info->data_file_name)
4897
3739
    {
4898
3740
      /* Fix data_file_name to have 'tmp_name' as basename */
4899
 
      strmov(data_file, tmp_name);
 
3741
      my_stpcpy(data_file, tmp_name);
4900
3742
      create_info->data_file_name=fn_same(data_file,
4901
3743
                                          create_info->data_file_name,
4902
3744
                                          1);
4905
3747
  else
4906
3748
    create_info->data_file_name=create_info->index_file_name=0;
4907
3749
 
4908
 
  if (new_db_type == old_db_type)
4909
 
  {
4910
 
    /*
4911
 
       Table has not changed storage engine.
4912
 
       If STORAGE and TABLESPACE have not been changed than copy them
4913
 
       from the original table
4914
 
    */
4915
 
    if (!create_info->tablespace &&
4916
 
        table->s->tablespace &&
4917
 
        create_info->default_storage_media == HA_SM_DEFAULT)
4918
 
      create_info->tablespace= table->s->tablespace;
4919
 
    if (create_info->default_storage_media == HA_SM_DEFAULT)
4920
 
      create_info->default_storage_media= table->s->default_storage_media;
4921
 
   }
4922
 
 
4923
3750
  /*
4924
3751
    Create a table with a temporary name.
4925
3752
    With create_info->frm_only == 1 this creates a .frm file only.
4930
3757
                            create_info, alter_info, 1, 0);
4931
3758
  reenable_binlog(thd);
4932
3759
 
4933
 
  DBUG_RETURN(error);
 
3760
  return(error);
4934
3761
}
4935
3762
 
4936
3763
/*
4953
3780
    The temporary table is created without storing it in any storage engine
4954
3781
    and is opened only to get the table struct and frm file reference.
4955
3782
*/
4956
 
TABLE *create_altered_table(THD *thd,
4957
 
                            TABLE *table,
 
3783
Table *create_altered_table(THD *thd,
 
3784
                            Table *table,
4958
3785
                            char *new_db,
4959
3786
                            HA_CREATE_INFO *create_info,
4960
3787
                            Alter_info *alter_info,
4962
3789
{
4963
3790
  int error;
4964
3791
  HA_CREATE_INFO altered_create_info(*create_info);
4965
 
  TABLE *altered_table;
 
3792
  Table *altered_table;
4966
3793
  char tmp_name[80];
4967
3794
  char path[FN_REFLEN];
4968
 
  DBUG_ENTER("create_altered_table");
4969
3795
 
4970
 
  my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
4971
 
              tmp_file_prefix, current_pid, thd->thread_id);
 
3796
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
 
3797
           tmp_file_prefix, current_pid, thd->thread_id);
4972
3798
  /* Safety fix for InnoDB */
4973
3799
  if (lower_case_table_names)
4974
3800
    my_casedn_str(files_charset_info, tmp_name);
4978
3804
                                     &altered_create_info,
4979
3805
                                     alter_info, db_change)))
4980
3806
  {
4981
 
    DBUG_PRINT("info", ("Error %u while creating temporary table", error));
4982
 
    DBUG_RETURN(NULL);
 
3807
    return(NULL);
4983
3808
  };
4984
3809
 
4985
3810
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4986
3811
                       FN_IS_TMP);
4987
3812
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
4988
3813
                                      OTM_ALTER);
4989
 
  DBUG_RETURN(altered_table);
 
3814
  return(altered_table);
4990
3815
 
4991
 
  DBUG_RETURN(NULL);
 
3816
  return(NULL);
4992
3817
}
4993
3818
 
4994
3819
 
5018
3843
    the table.
5019
3844
*/
5020
3845
int mysql_fast_or_online_alter_table(THD *thd,
5021
 
                                     TABLE *table,
5022
 
                                     TABLE *altered_table,
 
3846
                                     Table *table,
 
3847
                                     Table *altered_table,
5023
3848
                                     HA_CREATE_INFO *create_info,
5024
3849
                                     HA_ALTER_INFO *alter_info,
5025
3850
                                     HA_ALTER_FLAGS *ha_alter_flags,
5027
3852
{
5028
3853
  int error= 0;
5029
3854
  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER)?true:false;
5030
 
  TABLE *t_table;
 
3855
  Table *t_table;
5031
3856
 
5032
 
  DBUG_ENTER(" mysql_fast_or_online_alter_table");
5033
3857
  if (online)
5034
3858
  {
5035
3859
   /*
5063
3887
    The final .frm file is already created as a temporary file
5064
3888
    and will be renamed to the original table name.
5065
3889
  */
5066
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
3890
  pthread_mutex_lock(&LOCK_open);
5067
3891
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5068
3892
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
5069
3893
                          keys_onoff);
5077
3901
                         table->s->table_name.str, FN_FROM_IS_TMP))
5078
3902
  {
5079
3903
    error= 1;
5080
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3904
    pthread_mutex_unlock(&LOCK_open);
5081
3905
    goto err;
5082
3906
  }
5083
3907
  broadcast_refresh();
5084
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3908
  pthread_mutex_unlock(&LOCK_open);
5085
3909
 
5086
3910
  /*
5087
 
    The ALTER TABLE is always in its own transaction.
 
3911
    The ALTER Table is always in its own transaction.
5088
3912
    Commit must not be called while LOCK_open is locked. It could call
5089
3913
    wait_if_global_read_lock(), which could create a deadlock if called
5090
3914
    with LOCK_open.
5097
3921
    goto err;
5098
3922
  if (online)
5099
3923
  {
5100
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3924
    pthread_mutex_lock(&LOCK_open);
5101
3925
    if (reopen_table(table))
5102
3926
    {
5103
3927
      error= -1;
5104
3928
      goto err;
5105
3929
    }
5106
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3930
    pthread_mutex_unlock(&LOCK_open);
5107
3931
    t_table= table;
5108
3932
 
5109
3933
   /*
5117
3941
 
5118
3942
    /*
5119
3943
      We are going to reopen table down on the road, so we have to restore
5120
 
      state of the TABLE object which we used for obtaining of handler
 
3944
      state of the Table object which we used for obtaining of handler
5121
3945
      object to make it suitable for reopening.
5122
3946
    */
5123
 
    DBUG_ASSERT(t_table == table);
 
3947
    assert(t_table == table);
5124
3948
    table->open_placeholder= 1;
5125
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3949
    pthread_mutex_lock(&LOCK_open);
5126
3950
    close_handle_and_leave_table_as_lock(table);
5127
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3951
    pthread_mutex_unlock(&LOCK_open);
5128
3952
  }
5129
3953
 
5130
3954
 err:
5131
3955
  if (error)
5132
 
    DBUG_PRINT("info", ("Got error %u", error));
5133
 
  DBUG_RETURN(error);
 
3956
    return(error);
 
3957
  return 0;
5134
3958
}
5135
3959
 
5136
3960
 
5137
3961
/**
5138
 
  Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
 
3962
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
5139
3963
 
5140
 
  This function transforms parse output of ALTER TABLE - lists of
 
3964
  This function transforms parse output of ALTER Table - lists of
5141
3965
  columns and keys to add, drop or modify into, essentially,
5142
3966
  CREATE TABLE definition - a list of columns and keys of the new
5143
3967
  table. While doing so, it also performs some (bug not all)
5144
3968
  semantic checks.
5145
3969
 
5146
3970
  This function is invoked when we know that we're going to
5147
 
  perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
 
3971
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
5148
3972
  is not possible, perhaps because the ALTER statement contains
5149
3973
  instructions that require change in table data, not only in
5150
3974
  table definition or indexes.
5155
3979
                              Used as an interface to the storage engine
5156
3980
                              to acquire additional information about
5157
3981
                              the original table.
5158
 
  @param[in,out]  create_info A blob with CREATE/ALTER TABLE
 
3982
  @param[in,out]  create_info A blob with CREATE/ALTER Table
5159
3983
                              parameters
5160
3984
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
5161
3985
                              Originally create_info was used only in
5162
 
                              CREATE TABLE and alter_info only in ALTER TABLE.
 
3986
                              CREATE TABLE and alter_info only in ALTER Table.
5163
3987
                              But since ALTER might end-up doing CREATE,
5164
3988
                              this distinction is gone and we just carry
5165
3989
                              around two structures.
5170
3994
    Sets create_info->varchar if the table has a VARCHAR column.
5171
3995
    Prepares alter_info->create_list and alter_info->key_list with
5172
3996
    columns and keys of the new table.
5173
 
  @retval TRUE   error, out of memory or a semantical error in ALTER
5174
 
                 TABLE instructions
5175
 
  @retval FALSE  success
 
3997
  @retval true   error, out of memory or a semantical error in ALTER
 
3998
                 Table instructions
 
3999
  @retval false  success
5176
4000
*/
5177
4001
 
5178
4002
static bool
5179
 
mysql_prepare_alter_table(THD *thd, TABLE *table,
 
4003
mysql_prepare_alter_table(THD *thd, Table *table,
5180
4004
                          HA_CREATE_INFO *create_info,
5181
4005
                          Alter_info *alter_info)
5182
4006
{
5191
4015
  List_iterator<Create_field> find_it(new_create_list);
5192
4016
  List_iterator<Create_field> field_it(new_create_list);
5193
4017
  List<Key_part_spec> key_parts;
5194
 
  uint db_create_options= (table->s->db_create_options
 
4018
  uint32_t db_create_options= (table->s->db_create_options
5195
4019
                           & ~(HA_OPTION_PACK_RECORD));
5196
 
  uint used_fields= create_info->used_fields;
 
4020
  uint32_t used_fields= create_info->used_fields;
5197
4021
  KEY *key_info=table->key_info;
5198
 
  bool rc= TRUE;
5199
 
 
5200
 
  DBUG_ENTER("mysql_prepare_alter_table");
5201
 
 
5202
 
  create_info->varchar= FALSE;
 
4022
  bool rc= true;
 
4023
 
 
4024
 
 
4025
  create_info->varchar= false;
5203
4026
  /* Let new create options override the old ones */
5204
4027
  if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
5205
4028
    create_info->min_rows= table->s->min_rows;
5207
4030
    create_info->max_rows= table->s->max_rows;
5208
4031
  if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
5209
4032
    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;
5210
4035
  if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
5211
4036
    create_info->default_table_charset= table->s->table_charset;
5212
4037
  if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
5217
4042
  }
5218
4043
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
5219
4044
    create_info->key_block_size= table->s->key_block_size;
5220
 
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
5221
 
    create_info->transactional= table->s->transactional;
5222
4045
 
5223
4046
  restore_record(table, s->default_values);     // Empty record for DEFAULT
5224
4047
  Create_field *def;
5229
4052
  Field **f_ptr,*field;
5230
4053
  for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
5231
4054
    {
5232
 
    if (field->type() == MYSQL_TYPE_STRING)
5233
 
      create_info->varchar= TRUE;
5234
4055
    /* Check if field should be dropped */
5235
4056
    Alter_drop *drop;
5236
4057
    drop_it.rewind();
5265
4086
    if (def)
5266
4087
    {                                           // Field is changed
5267
4088
      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
      }
5268
4096
      if (!def->after)
5269
4097
        {
5270
4098
        new_create_list.push_back(def);
5288
4116
        }
5289
4117
      if (alter)
5290
4118
        {
5291
 
        if (def->sql_type == MYSQL_TYPE_BLOB)
 
4119
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
5292
4120
        {
5293
4121
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
5294
4122
          goto err;
5314
4142
      either has a default value or the '0000-00-00' is allowed by the
5315
4143
      set sql mode.
5316
4144
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
5317
 
      flag to allow ALTER TABLE only if the table to be altered is empty.
 
4145
      flag to allow ALTER Table only if the table to be altered is empty.
5318
4146
      */
5319
 
    if ((def->sql_type == MYSQL_TYPE_DATE ||
5320
 
         def->sql_type == MYSQL_TYPE_NEWDATE ||
5321
 
         def->sql_type == MYSQL_TYPE_DATETIME) &&
 
4147
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
 
4148
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
5322
4149
         !alter_info->datetime_field &&
5323
4150
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
5324
4151
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
5325
4152
    {
5326
4153
        alter_info->datetime_field= def;
5327
 
        alter_info->error_if_not_empty= TRUE;
 
4154
        alter_info->error_if_not_empty= true;
5328
4155
    }
5329
4156
    if (!def->after)
5330
4157
      new_create_list.push_back(def);
5347
4174
      find_it.after(def);                       // Put element after this
5348
4175
      /*
5349
4176
        XXX: hack for Bug#28427.
5350
 
        If column order has changed, force OFFLINE ALTER TABLE
 
4177
        If column order has changed, force OFFLINE ALTER Table
5351
4178
        without querying engine capabilities.  If we ever have an
5352
 
        engine that supports online ALTER TABLE CHANGE COLUMN
 
4179
        engine that supports online ALTER Table CHANGE COLUMN
5353
4180
        <name> AFTER <name1> (Falcon?), this fix will effectively
5354
4181
        disable the capability.
5355
4182
        TODO: detect the situation in compare_tables, behave based
5381
4208
    for which some fields exists.
5382
4209
    */
5383
4210
 
5384
 
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
 
4211
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
5385
4212
    {
5386
4213
    char *key_name= key_info->name;
5387
4214
    Alter_drop *drop;
5400
4227
 
5401
4228
    KEY_PART_INFO *key_part= key_info->key_part;
5402
4229
    key_parts.empty();
5403
 
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
 
4230
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
5404
4231
    {
5405
4232
      if (!key_part->field)
5406
4233
        continue;                               // Wrong field (from UNIREG)
5421
4248
      }
5422
4249
      if (!cfield)
5423
4250
        continue;                               // Field is removed
5424
 
      uint key_part_length=key_part->length;
 
4251
      uint32_t key_part_length=key_part->length;
5425
4252
      if (cfield->field)                        // Not new field
5426
4253
      {
5427
4254
        /*
5454
4281
      KEY_CREATE_INFO key_create_info;
5455
4282
      Key *key;
5456
4283
      enum Key::Keytype key_type;
5457
 
      bzero((char*) &key_create_info, sizeof(key_create_info));
 
4284
      memset(&key_create_info, 0, sizeof(key_create_info));
5458
4285
 
5459
4286
      key_create_info.algorithm= key_info->algorithm;
5460
4287
      if (key_info->flags & HA_USES_BLOCK_SIZE)
5483
4310
    Key *key;
5484
4311
    while ((key=key_it++))                      // Add new keys
5485
4312
    {
 
4313
      if (key->type == Key::FOREIGN_KEY &&
 
4314
          ((Foreign_key *)key)->validate(new_create_list))
 
4315
        goto err;
5486
4316
      if (key->type != Key::FOREIGN_KEY)
5487
4317
        new_key_list.push_back(key);
5488
4318
      if (key->name.str &&
5530
4360
  if (table->s->tmp_table)
5531
4361
    create_info->options|=HA_LEX_CREATE_TMP_TABLE;
5532
4362
 
5533
 
  rc= FALSE;
 
4363
  rc= false;
5534
4364
  alter_info->create_list.swap(new_create_list);
5535
4365
  alter_info->key_list.swap(new_key_list);
5536
4366
err:
5537
 
  DBUG_RETURN(rc);
 
4367
  return(rc);
5538
4368
}
5539
4369
 
5540
4370
 
5551
4381
      table_list       The table to change.
5552
4382
      alter_info       Lists of fields, keys to be changed, added
5553
4383
                       or dropped.
5554
 
      order_num        How many ORDER BY fields has been specified.
5555
 
      order            List of fields to ORDER BY.
5556
 
      ignore           Whether we have ALTER IGNORE TABLE
 
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
5557
4387
 
5558
4388
  DESCRIPTION
5559
4389
    This is a veery long function and is everything but the kitchen sink :)
5560
 
    It is used to alter a table and not only by ALTER TABLE but also
 
4390
    It is used to alter a table and not only by ALTER Table but also
5561
4391
    CREATE|DROP INDEX are mapped on this function.
5562
4392
 
5563
 
    When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
 
4393
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
5564
4394
    or both, then this function short cuts its operation by renaming
5565
4395
    the table and/or enabling/disabling the keys. In this case, the FRM is
5566
4396
    not changed, directly by mysql_alter_table. However, if there is a
5576
4406
    tables.
5577
4407
 
5578
4408
  RETURN VALUES
5579
 
    FALSE  OK
5580
 
    TRUE   Error
 
4409
    false  OK
 
4410
    true   Error
5581
4411
*/
5582
4412
 
5583
4413
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
5584
4414
                       HA_CREATE_INFO *create_info,
5585
 
                       TABLE_LIST *table_list,
 
4415
                       TableList *table_list,
5586
4416
                       Alter_info *alter_info,
5587
 
                       uint order_num, ORDER *order, bool ignore)
 
4417
                       uint32_t order_num, order_st *order, bool ignore)
5588
4418
{
5589
 
  TABLE *table, *new_table=0, *name_lock= 0;;
 
4419
  Table *table, *new_table=0, *name_lock= 0;;
5590
4420
  int error= 0;
5591
4421
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
5592
4422
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
5594
4424
  ha_rows copied= 0,deleted= 0;
5595
4425
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
5596
4426
  legacy_db_type table_type;
5597
 
  frm_type_enum frm_type;
5598
 
  DBUG_ENTER("mysql_alter_table");
5599
4427
 
5600
4428
  if (table_list && table_list->schema_table)
5601
4429
  {
5602
4430
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
5603
 
    DBUG_RETURN(TRUE);
 
4431
    return(true);
5604
4432
  }
5605
4433
 
5606
4434
  /*
5608
4436
    to simplify further comparisons: we want to see if it's a RENAME
5609
4437
    later just by comparing the pointers, avoiding the need for strcmp.
5610
4438
  */
5611
 
  thd_proc_info(thd, "init");
 
4439
  thd->set_proc_info("init");
5612
4440
  table_name=table_list->table_name;
5613
4441
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
5614
4442
  db=table_list->db;
5616
4444
    new_db= db;
5617
4445
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
5618
4446
 
5619
 
  mysql_ha_rm_tables(thd, table_list, FALSE);
 
4447
  mysql_ha_rm_tables(thd, table_list, false);
5620
4448
 
5621
 
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
 
4449
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
5622
4450
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
5623
4451
    /* Conditionally writes to binlog. */
5624
 
    DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
5625
 
                                                   alter_info->tablespace_op));
 
4452
    return(mysql_discard_or_import_tablespace(thd,table_list,
 
4453
                                              alter_info->tablespace_op));
5626
4454
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
5627
 
           "/", table_name, reg_ext, NullS);
 
4455
           "/", table_name, reg_ext, NULL);
5628
4456
  (void) unpack_filename(new_name_buff, new_name_buff);
5629
4457
  /*
5630
4458
    If this is just a rename of a view, short cut to the
5631
4459
    following scenario: 1) lock LOCK_open 2) do a RENAME
5632
4460
    2) unlock LOCK_open.
5633
4461
    This is a copy-paste added to make sure
5634
 
    ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
 
4462
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
5635
4463
    as an independent branch in mysql_execute_command. The need
5636
 
    for a copy-paste arose because the main code flow of ALTER TABLE
 
4464
    for a copy-paste arose because the main code flow of ALTER Table
5637
4465
    ... RENAME tries to use open_ltable, which does not work for views
5638
4466
    (open_ltable was never modified to merge table lists of child tables
5639
4467
    into the main table list, like open_tables does).
5640
4468
    This code is wrong and will be removed, please do not copy.
5641
4469
  */
5642
 
  frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
 
4470
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
5643
4471
 
5644
4472
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
5645
 
    DBUG_RETURN(TRUE);
 
4473
    return(true);
5646
4474
  table->use_all_columns();
5647
4475
 
5648
 
  /*
5649
 
    Prohibit changing of the UNION list of a non-temporary MERGE table
5650
 
    under LOCK tables. It would be quite difficult to reuse a shrinked
5651
 
    set of tables from the old table or to open a new TABLE object for
5652
 
    an extended list and verify that they belong to locked tables.
5653
 
  */
5654
 
  if (thd->locked_tables &&
5655
 
      (create_info->used_fields & HA_CREATE_USED_UNION) &&
5656
 
      (table->s->tmp_table == NO_TMP_TABLE))
5657
 
  {
5658
 
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
5659
 
    DBUG_RETURN(TRUE);
5660
 
  }
5661
 
 
5662
4476
  /* Check that we are not trying to rename to an existing table */
5663
4477
  if (new_name)
5664
4478
  {
5665
 
    DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
5666
 
    strmov(new_name_buff,new_name);
5667
 
    strmov(new_alias= new_alias_buff, new_name);
 
4479
    my_stpcpy(new_name_buff,new_name);
 
4480
    my_stpcpy(new_alias= new_alias_buff, new_name);
5668
4481
    if (lower_case_table_names)
5669
4482
    {
5670
4483
      if (lower_case_table_names != 2)
5690
4503
        if (find_temporary_table(thd,new_db,new_name_buff))
5691
4504
        {
5692
4505
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
5693
 
          DBUG_RETURN(TRUE);
 
4506
          return(true);
5694
4507
        }
5695
4508
      }
5696
4509
      else
5697
4510
      {
5698
4511
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
5699
 
          DBUG_RETURN(TRUE);
 
4512
          return(true);
5700
4513
        if (!name_lock)
5701
4514
        {
5702
4515
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
5703
 
          DBUG_RETURN(TRUE);
 
4516
          return(true);
5704
4517
        }
5705
4518
 
5706
4519
        build_table_filename(new_name_buff, sizeof(new_name_buff),
5730
4543
    goto err;
5731
4544
  new_db_type= create_info->db_type;
5732
4545
 
5733
 
  if (new_db_type != old_db_type ||
 
4546
  if (new_db_type != old_db_type &&
5734
4547
      !table->file->can_switch_engines())
5735
4548
  {
 
4549
    assert(0);
5736
4550
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
5737
4551
    goto err;
5738
4552
  }
5740
4554
  if (create_info->row_type == ROW_TYPE_NOT_USED)
5741
4555
    create_info->row_type= table->s->row_type;
5742
4556
 
5743
 
  DBUG_PRINT("info", ("old type: %s  new type: %s",
5744
 
             ha_resolve_storage_engine_name(old_db_type),
5745
 
             ha_resolve_storage_engine_name(new_db_type)));
5746
4557
  if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
5747
4558
      ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
5748
4559
  {
5749
 
    DBUG_PRINT("info", ("doesn't support alter"));
5750
4560
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
5751
4561
    goto err;
5752
4562
  }
5753
4563
 
5754
 
  thd_proc_info(thd, "setup");
 
4564
  thd->set_proc_info("setup");
5755
4565
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
5756
4566
      !table->s->tmp_table) // no need to touch frm
5757
4567
  {
5761
4571
    case ENABLE:
5762
4572
      /*
5763
4573
        wait_while_table_is_used() ensures that table being altered is
5764
 
        opened only by this thread and that TABLE::TABLE_SHARE::version
5765
 
        of TABLE object corresponding to this table is 0.
 
4574
        opened only by this thread and that Table::TABLE_SHARE::version
 
4575
        of Table object corresponding to this table is 0.
5766
4576
        The latter guarantees that no DML statement will open this table
5767
 
        until ALTER TABLE finishes (i.e. until close_thread_tables())
 
4577
        until ALTER Table finishes (i.e. until close_thread_tables())
5768
4578
        while the fact that the table is still open gives us protection
5769
4579
        from concurrent DDL statements.
5770
4580
      */
5771
 
      VOID(pthread_mutex_lock(&LOCK_open));
 
4581
      pthread_mutex_lock(&LOCK_open);
5772
4582
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5773
 
      VOID(pthread_mutex_unlock(&LOCK_open));
5774
 
      DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
 
4583
      pthread_mutex_unlock(&LOCK_open);
5775
4584
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
5776
4585
      /* COND_refresh will be signaled in close_thread_tables() */
5777
4586
      break;
5778
4587
    case DISABLE:
5779
 
      VOID(pthread_mutex_lock(&LOCK_open));
 
4588
      pthread_mutex_lock(&LOCK_open);
5780
4589
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5781
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
4590
      pthread_mutex_unlock(&LOCK_open);
5782
4591
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
5783
4592
      /* COND_refresh will be signaled in close_thread_tables() */
5784
4593
      break;
5785
4594
    default:
5786
 
      DBUG_ASSERT(FALSE);
 
4595
      assert(false);
5787
4596
      error= 0;
5788
4597
      break;
5789
4598
    }
5790
4599
    if (error == HA_ERR_WRONG_COMMAND)
5791
4600
    {
5792
4601
      error= 0;
5793
 
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
4602
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5794
4603
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
5795
4604
                          table->alias);
5796
4605
    }
5797
4606
 
5798
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
4607
    pthread_mutex_lock(&LOCK_open);
5799
4608
    /*
5800
4609
      Unlike to the above case close_cached_table() below will remove ALL
5801
 
      instances of TABLE from table cache (it will also remove table lock
 
4610
      instances of Table from table cache (it will also remove table lock
5802
4611
      held by this thread). So to make actual table renaming and writing
5803
4612
      to binlog atomic we have to put them into the same critical section
5804
4613
      protected by LOCK_open mutex. This also removes gap for races between
5807
4616
 
5808
4617
    if (!error && (new_name != table_name || new_db != db))
5809
4618
    {
5810
 
      thd_proc_info(thd, "rename");
 
4619
      thd->set_proc_info("rename");
5811
4620
      /*
5812
4621
        Then do a 'simple' rename of the table. First we need to close all
5813
4622
        instances of 'source' table.
5833
4642
          error= -1;
5834
4643
        else if (0)
5835
4644
      {
5836
 
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
5837
 
                                  table_name, 0));
 
4645
          mysql_rename_table(old_db_type, new_db, new_alias, db,
 
4646
                             table_name, 0);
5838
4647
          error= -1;
5839
4648
      }
5840
4649
    }
5843
4652
    if (error == HA_ERR_WRONG_COMMAND)
5844
4653
  {
5845
4654
      error= 0;
5846
 
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
4655
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5847
4656
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
5848
4657
                          table->alias);
5849
4658
  }
5850
4659
 
5851
4660
    if (!error)
5852
4661
    {
5853
 
      write_bin_log(thd, TRUE, thd->query, thd->query_length);
 
4662
      write_bin_log(thd, true, thd->query, thd->query_length);
5854
4663
      my_ok(thd);
5855
4664
  }
5856
4665
    else if (error > 0)
5859
4668
      error= -1;
5860
4669
    }
5861
4670
    if (name_lock)
5862
 
      unlink_open_table(thd, name_lock, FALSE);
5863
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4671
      unlink_open_table(thd, name_lock, false);
 
4672
    pthread_mutex_unlock(&LOCK_open);
5864
4673
    table_list->table= NULL;                    // For query cache
5865
 
    DBUG_RETURN(error);
 
4674
    return(error);
5866
4675
  }
5867
4676
 
5868
4677
  /* We have to do full alter table. */
5869
4678
 
5870
4679
    /*
5871
 
    If the old table had partitions and we are doing ALTER TABLE ...
 
4680
    If the old table had partitions and we are doing ALTER Table ...
5872
4681
    engine= <new_engine>, the new table must preserve the original
5873
4682
    partitioning. That means that the new engine is still the
5874
4683
    partitioning engine, not the engine specified in the parser.
5900
4709
 
5901
4710
  if (alter_info->build_method != HA_BUILD_OFFLINE)
5902
4711
  {
5903
 
    TABLE *altered_table= 0;
 
4712
    Table *altered_table= 0;
5904
4713
    HA_ALTER_INFO ha_alter_info;
5905
4714
    HA_ALTER_FLAGS ha_alter_flags;
5906
 
    uint table_changes= IS_EQUAL_YES;
5907
 
    bool need_copy_table= TRUE;
 
4715
    uint32_t table_changes= IS_EQUAL_YES;
 
4716
    bool need_copy_table= true;
5908
4717
    /* Check how much the tables differ. */
5909
4718
    if (compare_tables(thd, table, alter_info,
5910
4719
                       create_info, order_num,
5912
4721
                       &ha_alter_info,
5913
4722
                       &table_changes))
5914
4723
    {
5915
 
      DBUG_RETURN(TRUE);
 
4724
      return(true);
5916
4725
    }
5917
4726
 
5918
4727
    /*
5920
4729
      on-line.
5921
4730
    */
5922
4731
 
5923
 
#ifndef DBUG_OFF
5924
 
    {
5925
 
      char dbug_string[HA_MAX_ALTER_FLAGS+1];
5926
 
      ha_alter_flags.print(dbug_string);
5927
 
      DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
5928
 
                          need_copy_table, table_changes,
5929
 
                          (char *) dbug_string));
5930
 
    }
5931
 
#endif
5932
4732
 
5933
4733
    /*
5934
4734
      If table is not renamed, changed database and
5961
4761
        /*
5962
4762
          @todo: Currently we always acquire an exclusive name
5963
4763
          lock on the table metadata when performing fast or online
5964
 
          ALTER TABLE. In future we may consider this unnecessary,
 
4764
          ALTER Table. In future we may consider this unnecessary,
5965
4765
          and narrow the scope of the exclusive name lock to only
5966
4766
          cover manipulation with .frms. Storage engine API
5967
4767
          call check_if_supported_alter has provision for this
5968
4768
          already now.
5969
4769
        */
5970
 
        need_copy_table= FALSE;
 
4770
        need_copy_table= false;
5971
4771
        break;
5972
4772
      case HA_ALTER_NOT_SUPPORTED:
5973
4773
        if (alter_info->build_method == HA_BUILD_ONLINE)
5976
4776
          close_temporary_table(thd, altered_table, 1, 1);
5977
4777
          goto err;
5978
4778
        }
5979
 
        need_copy_table= TRUE;
 
4779
        need_copy_table= true;
5980
4780
        break;
5981
4781
      case HA_ALTER_ERROR:
5982
4782
      default:
5983
4783
        close_temporary_table(thd, altered_table, 1, 1);
5984
4784
        goto err;
5985
4785
      }
5986
 
#ifndef DBUG_OFF
5987
 
      {
5988
 
        char dbug_string[HA_MAX_ALTER_FLAGS+1];
5989
 
        ha_alter_flags.print(dbug_string);
5990
 
        DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
5991
 
                            need_copy_table, table_changes,
5992
 
                            (char *) dbug_string));
5993
 
      }
5994
 
#endif
5995
4786
 
5996
4787
    }
5997
 
    /* TODO need to check if changes can be handled as fast ALTER TABLE */
 
4788
    /* TODO need to check if changes can be handled as fast ALTER Table */
5998
4789
    if (!altered_table)
5999
 
      need_copy_table= TRUE;
 
4790
      need_copy_table= true;
6000
4791
 
6001
4792
    if (!need_copy_table)
6002
4793
    {
6034
4825
      close_temporary_table(thd, altered_table, 1, 1);
6035
4826
  }
6036
4827
 
6037
 
  my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
6038
 
              current_pid, thd->thread_id);
 
4828
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
 
4829
           current_pid, thd->thread_id);
6039
4830
  /* Safety fix for innodb */
6040
4831
  if (lower_case_table_names)
6041
4832
    my_casedn_str(files_charset_info, tmp_name);
6052
4843
  /* Open the table so we need to copy the data to it. */
6053
4844
  if (table->s->tmp_table)
6054
4845
  {
6055
 
    TABLE_LIST tbl;
6056
 
    bzero((void*) &tbl, sizeof(tbl));
 
4846
    TableList tbl;
 
4847
    memset(&tbl, 0, sizeof(tbl));
6057
4848
    tbl.db= new_db;
6058
4849
    tbl.table_name= tbl.alias= tmp_name;
6059
4850
    /* Table is in thd->temporary_tables */
6060
 
    new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
6061
 
                          MYSQL_LOCK_IGNORE_FLUSH);
 
4851
    new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
6062
4852
  }
6063
4853
  else
6064
4854
  {
6075
4865
  /* Copy the data if necessary. */
6076
4866
  thd->count_cuted_fields= CHECK_FIELD_WARN;    // calc cuted fields
6077
4867
  thd->cuted_fields=0L;
6078
 
  thd_proc_info(thd, "copy to tmp table");
 
4868
  thd->set_proc_info("copy to tmp table");
6079
4869
  copied=deleted=0;
6080
4870
  /*
6081
4871
    We do not copy data for MERGE tables. Only the children have data.
6083
4873
  */
6084
4874
  if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
6085
4875
  {
6086
 
    /* We don't want update TIMESTAMP fields during ALTER TABLE. */
 
4876
    /* We don't want update TIMESTAMP fields during ALTER Table. */
6087
4877
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
6088
4878
    new_table->next_number_field=new_table->found_next_number_field;
6089
4879
    error= copy_data_between_tables(table, new_table,
6094
4884
  }
6095
4885
  else
6096
4886
  {
6097
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
4887
    pthread_mutex_lock(&LOCK_open);
6098
4888
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
6099
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4889
    pthread_mutex_unlock(&LOCK_open);
6100
4890
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
6101
4891
                            alter_info->keys_onoff);
6102
4892
    error= ha_autocommit_or_rollback(thd, 0);
6123
4913
      goto err1;
6124
4914
    /* We don't replicate alter table statement on temporary tables */
6125
4915
    if (!thd->current_stmt_binlog_row_based)
6126
 
      write_bin_log(thd, TRUE, thd->query, thd->query_length);
 
4916
      write_bin_log(thd, true, thd->query, thd->query_length);
6127
4917
    goto end_temporary;
6128
4918
  }
6129
4919
 
6134
4924
      Note that MERGE tables do not have their children attached here.
6135
4925
    */
6136
4926
    intern_close_table(new_table);
6137
 
    my_free(new_table,MYF(0));
 
4927
    free(new_table);
6138
4928
  }
6139
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
4929
  pthread_mutex_lock(&LOCK_open);
6140
4930
  if (error)
6141
4931
  {
6142
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
6143
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4932
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
4933
    pthread_mutex_unlock(&LOCK_open);
6144
4934
    goto err;
6145
4935
  }
6146
4936
 
6151
4941
       with exclusive name-locks.
6152
4942
    3) Rename the old table to a temp name, rename the new one to the
6153
4943
       old name.
6154
 
    4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
 
4944
    4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
6155
4945
       we reopen new version of table.
6156
4946
    5) Write statement to the binary log.
6157
 
    6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
 
4947
    6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
6158
4948
       remove name-locks from list of open tables and table cache.
6159
4949
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
6160
4950
       call to remove name-locks from table cache and list of open table.
6161
4951
  */
6162
4952
 
6163
 
  thd_proc_info(thd, "rename result table");
6164
 
  my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
6165
 
              current_pid, thd->thread_id);
 
4953
  thd->set_proc_info("rename result table");
 
4954
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
 
4955
           current_pid, thd->thread_id);
6166
4956
  if (lower_case_table_names)
6167
4957
    my_casedn_str(files_charset_info, old_name);
6168
4958
 
6177
4967
    mysql_rename_table(), because we just juggle with the FRM and nothing
6178
4968
    more. If we have an intermediate table, then we notify the SE that
6179
4969
    it should become the actual table. Later, we will recycle the old table.
6180
 
    However, in case of ALTER TABLE RENAME there might be no intermediate
 
4970
    However, in case of ALTER Table RENAME there might be no intermediate
6181
4971
    table. This is when the old and new tables are compatible, according to
6182
4972
    compare_table(). Then, we need one additional call to
6183
4973
    mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
6189
4979
                         FN_TO_IS_TMP))
6190
4980
  {
6191
4981
    error=1;
6192
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
4982
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
6193
4983
  }
6194
4984
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
6195
4985
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
6196
4986
  {
6197
4987
    /* Try to get everything back. */
6198
4988
    error=1;
6199
 
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
6200
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
6201
 
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
6202
 
                            FN_FROM_IS_TMP));
 
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);
6203
4993
  }
6204
4994
 
6205
4995
  if (error)
6208
4998
    goto err_with_placeholders;
6209
4999
  }
6210
5000
 
6211
 
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
 
5001
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
6212
5002
 
6213
5003
end_online:
6214
5004
  if (thd->locked_tables && new_name == table_name && new_db == db)
6219
5009
    if (error)
6220
5010
      goto err_with_placeholders;
6221
5011
  }
6222
 
  VOID(pthread_mutex_unlock(&LOCK_open));
6223
 
 
6224
 
  thd_proc_info(thd, "end");
6225
 
 
6226
 
  DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
6227
 
 
6228
 
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
6229
 
                      thd->query, thd->query_length,
6230
 
                      db, table_name);
6231
 
 
6232
 
  DBUG_ASSERT(!(mysql_bin_log.is_open() &&
 
5012
  pthread_mutex_unlock(&LOCK_open);
 
5013
 
 
5014
  thd->set_proc_info("end");
 
5015
 
 
5016
  assert(!(mysql_bin_log.is_open() &&
6233
5017
                thd->current_stmt_binlog_row_based &&
6234
5018
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
6235
 
  write_bin_log(thd, TRUE, thd->query, thd->query_length);
 
5019
  write_bin_log(thd, true, thd->query, thd->query_length);
6236
5020
 
6237
5021
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
6238
5022
  {
6242
5026
      shutdown. But we do not need to attach MERGE children.
6243
5027
    */
6244
5028
    char path[FN_REFLEN];
6245
 
    TABLE *t_table;
 
5029
    Table *t_table;
6246
5030
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
6247
 
    t_table= open_temporary_table(thd, path, new_db, tmp_name, FALSE, OTM_OPEN);
 
5031
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
6248
5032
    if (t_table)
6249
5033
    {
6250
5034
      intern_close_table(t_table);
6251
 
      my_free(t_table, MYF(0));
 
5035
      free(t_table);
6252
5036
    }
6253
5037
    else
6254
 
      sql_print_warning("Could not open table %s.%s after rename\n",
 
5038
      sql_print_warning(_("Could not open table %s.%s after rename\n"),
6255
5039
                        new_db,table_name);
6256
5040
    ha_flush_logs(old_db_type);
6257
5041
  }
6260
5044
  if (thd->locked_tables && (new_name != table_name || new_db != db))
6261
5045
  {
6262
5046
    /*
6263
 
      If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
 
5047
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
6264
5048
      to remove placeholders for the old table and for the target table
6265
5049
      from the list of open tables and table cache. If we are not under
6266
5050
      LOCK TABLES we can rely on close_thread_tables() doing this job.
6267
5051
    */
6268
5052
    pthread_mutex_lock(&LOCK_open);
6269
 
    unlink_open_table(thd, table, FALSE);
6270
 
    unlink_open_table(thd, name_lock, FALSE);
 
5053
    unlink_open_table(thd, table, false);
 
5054
    unlink_open_table(thd, name_lock, false);
6271
5055
    pthread_mutex_unlock(&LOCK_open);
6272
5056
  }
6273
5057
 
6274
5058
end_temporary:
6275
 
  my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
6276
 
              (ulong) (copied + deleted), (ulong) deleted,
6277
 
              (ulong) thd->cuted_fields);
 
5059
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 
5060
           (ulong) (copied + deleted), (ulong) deleted,
 
5061
           (ulong) thd->cuted_fields);
6278
5062
  my_ok(thd, copied + deleted, 0L, tmp_name);
6279
5063
  thd->some_tables_deleted=0;
6280
 
  DBUG_RETURN(FALSE);
 
5064
  return(false);
6281
5065
 
6282
5066
err1:
6283
5067
  if (new_table)
6286
5070
    close_temporary_table(thd, new_table, 1, 1);
6287
5071
  }
6288
5072
  else
6289
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5073
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
6290
5074
 
6291
5075
err:
6292
5076
  /*
6298
5082
  if (alter_info->error_if_not_empty && thd->row_count)
6299
5083
  {
6300
5084
    const char *f_val= 0;
6301
 
    enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
 
5085
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
6302
5086
    switch (alter_info->datetime_field->sql_type)
6303
5087
    {
6304
 
      case MYSQL_TYPE_DATE:
6305
 
      case MYSQL_TYPE_NEWDATE:
 
5088
      case DRIZZLE_TYPE_NEWDATE:
6306
5089
        f_val= "0000-00-00";
6307
 
        t_type= MYSQL_TIMESTAMP_DATE;
 
5090
        t_type= DRIZZLE_TIMESTAMP_DATE;
6308
5091
        break;
6309
 
      case MYSQL_TYPE_DATETIME:
 
5092
      case DRIZZLE_TYPE_DATETIME:
6310
5093
        f_val= "0000-00-00 00:00:00";
6311
 
        t_type= MYSQL_TIMESTAMP_DATETIME;
 
5094
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
6312
5095
        break;
6313
5096
      default:
6314
5097
        /* Shouldn't get here. */
6315
 
        DBUG_ASSERT(0);
 
5098
        assert(0);
6316
5099
    }
6317
5100
    bool save_abort_on_warning= thd->abort_on_warning;
6318
 
    thd->abort_on_warning= TRUE;
6319
 
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
 
5101
    thd->abort_on_warning= true;
 
5102
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
6320
5103
                                 f_val, strlength(f_val), t_type,
6321
5104
                                 alter_info->datetime_field->field_name);
6322
5105
    thd->abort_on_warning= save_abort_on_warning;
6324
5107
  if (name_lock)
6325
5108
  {
6326
5109
    pthread_mutex_lock(&LOCK_open);
6327
 
    unlink_open_table(thd, name_lock, FALSE);
 
5110
    unlink_open_table(thd, name_lock, false);
6328
5111
    pthread_mutex_unlock(&LOCK_open);
6329
5112
  }
6330
 
  DBUG_RETURN(TRUE);
 
5113
  return(true);
6331
5114
 
6332
5115
err_with_placeholders:
6333
5116
  /*
6335
5118
    being altered. To be safe under LOCK TABLES we should remove placeholders
6336
5119
    from list of open tables list and table cache.
6337
5120
  */
6338
 
  unlink_open_table(thd, table, FALSE);
 
5121
  unlink_open_table(thd, table, false);
6339
5122
  if (name_lock)
6340
 
    unlink_open_table(thd, name_lock, FALSE);
6341
 
  VOID(pthread_mutex_unlock(&LOCK_open));
6342
 
  DBUG_RETURN(TRUE);
 
5123
    unlink_open_table(thd, name_lock, false);
 
5124
  pthread_mutex_unlock(&LOCK_open);
 
5125
  return(true);
6343
5126
}
6344
5127
/* mysql_alter_table */
6345
5128
 
6346
5129
static int
6347
 
copy_data_between_tables(TABLE *from,TABLE *to,
 
5130
copy_data_between_tables(Table *from,Table *to,
6348
5131
                         List<Create_field> &create,
6349
5132
                         bool ignore,
6350
 
                         uint order_num, ORDER *order,
 
5133
                         uint32_t order_num, order_st *order,
6351
5134
                         ha_rows *copied,
6352
5135
                         ha_rows *deleted,
6353
5136
                         enum enum_enable_or_disable keys_onoff,
6357
5140
  Copy_field *copy,*copy_end;
6358
5141
  ulong found_count,delete_count;
6359
5142
  THD *thd= current_thd;
6360
 
  uint length= 0;
 
5143
  uint32_t length= 0;
6361
5144
  SORT_FIELD *sortorder;
6362
5145
  READ_RECORD info;
6363
 
  TABLE_LIST   tables;
 
5146
  TableList   tables;
6364
5147
  List<Item>   fields;
6365
5148
  List<Item>   all_fields;
6366
5149
  ha_rows examined_rows;
6367
5150
  bool auto_increment_field_copied= 0;
6368
5151
  ulong save_sql_mode;
6369
 
  ulonglong prev_insert_id;
6370
 
  DBUG_ENTER("copy_data_between_tables");
 
5152
  uint64_t prev_insert_id;
6371
5153
 
6372
5154
  /*
6373
5155
    Turn off recovery logging since rollback of an alter table is to
6375
5157
    
6376
5158
    This needs to be done before external_lock
6377
5159
  */
6378
 
  error= ha_enable_transaction(thd, FALSE);
 
5160
  error= ha_enable_transaction(thd, false);
6379
5161
  if (error)
6380
 
    DBUG_RETURN(-1);
 
5162
    return(-1);
6381
5163
  
6382
5164
  if (!(copy= new Copy_field[to->s->fields]))
6383
 
    DBUG_RETURN(-1);                            /* purecov: inspected */
 
5165
    return(-1);                         /* purecov: inspected */
6384
5166
 
6385
5167
  if (to->file->ha_external_lock(thd, F_WRLCK))
6386
 
    DBUG_RETURN(-1);
 
5168
    return(-1);
6387
5169
 
6388
5170
  /* We need external lock before we can disable/enable keys */
6389
5171
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
6405
5187
    if (def->field)
6406
5188
    {
6407
5189
      if (*ptr == to->next_number_field)
6408
 
      {
6409
 
        auto_increment_field_copied= TRUE;
6410
 
        /*
6411
 
          If we are going to copy contents of one auto_increment column to
6412
 
          another auto_increment column it is sensible to preserve zeroes.
6413
 
          This condition also covers case when we are don't actually alter
6414
 
          auto_increment column.
6415
 
        */
6416
 
        if (def->field == from->found_next_number_field)
6417
 
          thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
6418
 
      }
 
5190
        auto_increment_field_copied= true;
 
5191
 
6419
5192
      (copy_end++)->set(*ptr,def->field,0);
6420
5193
    }
6421
5194
 
6427
5200
  {
6428
5201
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
6429
5202
    {
6430
 
      char warn_buff[MYSQL_ERRMSG_SIZE];
6431
 
      my_snprintf(warn_buff, sizeof(warn_buff), 
6432
 
                  "ORDER BY ignored as there is a user-defined clustered index"
6433
 
                  " in the table '%-.192s'", from->s->table_name.str);
6434
 
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
5203
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
5204
      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,
6435
5209
                   warn_buff);
6436
5210
    }
6437
5211
    else
6438
5212
    {
6439
5213
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
6440
5214
                                                MYF(MY_FAE | MY_ZEROFILL));
6441
 
      bzero((char *) &tables, sizeof(tables));
 
5215
      memset(&tables, 0, sizeof(tables));
6442
5216
      tables.table= from;
6443
5217
      tables.alias= tables.table_name= from->s->table_name.str;
6444
5218
      tables.db= from->s->db.str;
6481
5255
    if (to->next_number_field)
6482
5256
    {
6483
5257
      if (auto_increment_field_copied)
6484
 
        to->auto_increment_field_not_null= TRUE;
 
5258
        to->auto_increment_field_not_null= true;
6485
5259
      else
6486
5260
        to->next_number_field->reset();
6487
5261
    }
6491
5265
      copy_ptr->do_copy(copy_ptr);
6492
5266
    }
6493
5267
    prev_insert_id= to->file->next_insert_id;
 
5268
    update_virtual_fields_marked_for_write(to, false);
6494
5269
    error=to->file->ha_write_row(to->record[0]);
6495
 
    to->auto_increment_field_not_null= FALSE;
 
5270
    to->auto_increment_field_not_null= false;
6496
5271
    if (error)
6497
5272
    {
6498
5273
      if (!ignore ||
6500
5275
      {
6501
5276
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
6502
5277
         {
6503
 
           uint key_nr= to->file->get_dup_key(error);
 
5278
           uint32_t key_nr= to->file->get_dup_key(error);
6504
5279
           if ((int) key_nr >= 0)
6505
5280
           {
6506
5281
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
6533
5308
  }
6534
5309
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
6535
5310
 
6536
 
  if (ha_enable_transaction(thd, TRUE))
 
5311
  if (ha_enable_transaction(thd, true))
6537
5312
  {
6538
5313
    error= 1;
6539
5314
    goto err;
6557
5332
  to->file->ha_release_auto_increment();
6558
5333
  if (to->file->ha_external_lock(thd,F_UNLCK))
6559
5334
    error=1;
6560
 
  DBUG_RETURN(error > 0 ? -1 : 0);
 
5335
  return(error > 0 ? -1 : 0);
6561
5336
}
6562
5337
 
6563
5338
 
6572
5347
 RETURN
6573
5348
    Like mysql_alter_table().
6574
5349
*/
6575
 
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
 
5350
bool mysql_recreate_table(THD *thd, TableList *table_list)
6576
5351
{
6577
5352
  HA_CREATE_INFO create_info;
6578
5353
  Alter_info alter_info;
6579
5354
 
6580
 
  DBUG_ENTER("mysql_recreate_table");
6581
 
  DBUG_ASSERT(!table_list->next_global);
 
5355
  assert(!table_list->next_global);
6582
5356
  /*
6583
5357
    table_list->table has been closed and freed. Do not reference
6584
5358
    uninitialized data. open_tables() could fail.
6585
5359
  */
6586
5360
  table_list->table= NULL;
6587
5361
 
6588
 
  bzero((char*) &create_info, sizeof(create_info));
 
5362
  memset(&create_info, 0, sizeof(create_info));
6589
5363
  create_info.row_type=ROW_TYPE_NOT_USED;
6590
5364
  create_info.default_table_charset=default_charset_info;
6591
5365
  /* Force alter table to recreate table */
6592
5366
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
6593
 
  DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
 
5367
  return(mysql_alter_table(thd, NULL, NULL, &create_info,
6594
5368
                                table_list, &alter_info, 0,
6595
 
                                (ORDER *) 0, 0));
 
5369
                                (order_st *) 0, 0));
6596
5370
}
6597
5371
 
6598
5372
 
6599
 
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
 
5373
bool mysql_checksum_table(THD *thd, TableList *tables,
6600
5374
                          HA_CHECK_OPT *check_opt)
6601
5375
{
6602
 
  TABLE_LIST *table;
 
5376
  TableList *table;
6603
5377
  List<Item> field_list;
6604
5378
  Item *item;
6605
5379
  Protocol *protocol= thd->protocol;
6606
 
  DBUG_ENTER("mysql_checksum_table");
6607
5380
 
6608
5381
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
6609
5382
  item->maybe_null= 1;
6610
 
  field_list.push_back(item= new Item_int("Checksum", (longlong) 1,
 
5383
  field_list.push_back(item= new Item_int("Checksum", (int64_t) 1,
6611
5384
                                          MY_INT64_NUM_DECIMAL_DIGITS));
6612
5385
  item->maybe_null= 1;
6613
5386
  if (protocol->send_fields(&field_list,
6614
5387
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
6615
 
    DBUG_RETURN(TRUE);
 
5388
    return(true);
6616
5389
 
6617
5390
  /* Open one table after the other to keep lock time as short as possible. */
6618
5391
  for (table= tables; table; table= table->next_local)
6619
5392
  {
6620
5393
    char table_name[NAME_LEN*2+2];
6621
 
    TABLE *t;
 
5394
    Table *t;
6622
5395
 
6623
 
    strxmov(table_name, table->db ,".", table->table_name, NullS);
 
5396
    strxmov(table_name, table->db ,".", table->table_name, NULL);
6624
5397
 
6625
5398
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
6626
5399
    thd->clear_error();                 // these errors shouldn't get client
6638
5411
    {
6639
5412
      if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
6640
5413
          !(check_opt->flags & T_EXTEND))
6641
 
        protocol->store((ulonglong)t->file->checksum());
 
5414
        protocol->store((uint64_t)t->file->checksum());
6642
5415
      else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
6643
5416
               (check_opt->flags & T_QUICK))
6644
5417
        protocol->store_null();
6646
5419
      {
6647
5420
        /* calculating table's checksum */
6648
5421
        ha_checksum crc= 0;
6649
 
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
 
5422
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
6650
5423
 
6651
5424
        t->use_all_columns();
6652
5425
 
6674
5447
              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
6675
5448
            }
6676
5449
 
6677
 
            for (uint i= 0; i < t->s->fields; i++ )
 
5450
            for (uint32_t i= 0; i < t->s->fields; i++ )
6678
5451
            {
6679
5452
              Field *f= t->field[i];
6680
 
              if ((f->type() == MYSQL_TYPE_BLOB) ||
6681
 
                  (f->type() == MYSQL_TYPE_VARCHAR))
 
5453
              if ((f->type() == DRIZZLE_TYPE_BLOB) ||
 
5454
                  (f->type() == DRIZZLE_TYPE_VARCHAR))
6682
5455
              {
6683
5456
                String tmp;
6684
5457
                f->val_str(&tmp);
6685
 
                row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
 
5458
                row_crc= my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
6686
5459
              }
6687
5460
              else
6688
5461
                row_crc= my_checksum(row_crc, f->ptr,
6691
5464
 
6692
5465
            crc+= row_crc;
6693
5466
          }
6694
 
          protocol->store((ulonglong)crc);
 
5467
          protocol->store((uint64_t)crc);
6695
5468
          t->file->ha_rnd_end();
6696
5469
        }
6697
5470
      }
6704
5477
  }
6705
5478
 
6706
5479
  my_eof(thd);
6707
 
  DBUG_RETURN(FALSE);
 
5480
  return(false);
6708
5481
 
6709
5482
 err:
6710
5483
  close_thread_tables(thd);                     // Shouldn't be needed
6711
5484
  if (table)
6712
5485
    table->table=0;
6713
 
  DBUG_RETURN(TRUE);
 
5486
  return(true);
6714
5487
}
6715
5488
 
6716
5489
static bool check_engine(THD *thd, const char *table_name,
6721
5494
  bool no_substitution= 1;
6722
5495
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
6723
5496
                                  no_substitution, 1)))
6724
 
    return TRUE;
 
5497
    return true;
6725
5498
 
6726
5499
  if (req_engine && req_engine != *new_engine)
6727
5500
  {
6728
 
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
5501
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
6729
5502
                       ER_WARN_USING_OTHER_HANDLER,
6730
5503
                       ER(ER_WARN_USING_OTHER_HANDLER),
6731
5504
                       ha_resolve_storage_engine_name(*new_engine),
6739
5512
      my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
6740
5513
               ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
6741
5514
      *new_engine= 0;
6742
 
      return TRUE;
 
5515
      return true;
6743
5516
    }
6744
5517
    *new_engine= myisam_hton;
6745
5518
  }
6746
 
  return FALSE;
 
5519
  return false;
6747
5520
}