~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/sql_table.cc

  • Committer: Monty Taylor
  • Date: 2008-07-05 17:07:46 UTC
  • mto: This revision was merged to the branch mainline in revision 63.
  • Revision ID: monty@inaugust.com-20080705170746-8aq11u9fuwtfwy85
Removed my_alarm. Made my_lock only do the non-alarm version. Moved my_lock to MyISAM where it belongs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* drop and alter of tables */
17
17
 
18
 
#include <drizzled/server_includes.h>
19
 
#include <storage/myisam/myisam.h>
20
 
#include <drizzled/sql_show.h>
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
#include <libdrizzle/gettext.h>
 
18
#include "mysql_priv.h"
 
19
#include <hash.h>
 
20
#include <myisam.h>
 
21
#include <my_dir.h>
 
22
#include "sql_show.h"
23
23
 
24
24
int creating_table= 0;        // How many mysql_create_table are running
25
25
 
27
27
 
28
28
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
29
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
30
 
static int copy_data_between_tables(Table *from,Table *to,
 
30
static int copy_data_between_tables(TABLE *from,TABLE *to,
31
31
                                    List<Create_field> &create, bool ignore,
32
 
                                    uint32_t order_num, order_st *order,
 
32
                                    uint order_num, ORDER *order,
33
33
                                    ha_rows *copied,ha_rows *deleted,
34
34
                                    enum enum_enable_or_disable keys_onoff,
35
35
                                    bool error_if_not_empty);
40
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
41
41
                           Alter_info *alter_info,
42
42
                           bool tmp_table,
43
 
                               uint32_t *db_options,
 
43
                               uint *db_options,
44
44
                               handler *file, KEY **key_info_buffer,
45
 
                               uint32_t *key_count, int select_field_count);
 
45
                               uint *key_count, int select_field_count);
46
46
static bool
47
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
47
mysql_prepare_alter_table(THD *thd, TABLE *table,
48
48
                          HA_CREATE_INFO *create_info,
49
49
                          Alter_info *alter_info);
50
50
 
 
51
#ifndef DBUG_OFF
 
52
 
 
53
/* Wait until we get a 'mysql_kill' signal */
 
54
 
 
55
static void wait_for_kill_signal(THD *thd)
 
56
{
 
57
  while (thd->killed == 0)
 
58
    sleep(1);
 
59
  // Reset signal and continue as if nothing happend
 
60
  thd->killed= THD::NOT_KILLED;
 
61
}
 
62
#endif
 
63
 
 
64
 
51
65
/*
52
66
  Translate a file name to a table name (WL #1324).
53
67
 
60
74
  RETURN
61
75
    Table name length.
62
76
*/
63
 
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
 
77
 
 
78
uint filename_to_tablename(const char *from, char *to, uint to_length)
64
79
{
65
 
  uint32_t errors;
66
 
  uint32_t res;
 
80
  uint errors;
 
81
  uint res;
 
82
  DBUG_ENTER("filename_to_tablename");
 
83
  DBUG_PRINT("enter", ("from '%s'", from));
67
84
 
68
85
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
69
86
  {
70
87
    /* Temporary table name. */
71
 
    res= (my_stpncpy(to, from, to_length) - to);
 
88
    res= (strnmov(to, from, to_length) - to);
72
89
  }
73
90
  else
74
91
  {
76
93
                    system_charset_info,  to, to_length, &errors);
77
94
    if (errors) // Old 5.0 name
78
95
    {
79
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NULL) -
 
96
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
80
97
            to);
81
 
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
 
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
      */
82
103
    }
83
104
  }
84
105
 
85
 
  return(res);
 
106
  DBUG_PRINT("exit", ("to '%s'", to));
 
107
  DBUG_RETURN(res);
86
108
}
87
109
 
88
110
 
99
121
    File name length.
100
122
*/
101
123
 
102
 
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
 
124
uint tablename_to_filename(const char *from, char *to, uint to_length)
103
125
{
104
 
  uint32_t errors, length;
 
126
  uint errors, length;
 
127
  DBUG_ENTER("tablename_to_filename");
 
128
  DBUG_PRINT("enter", ("from '%s'", from));
105
129
 
106
130
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
107
131
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
108
 
    return((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
 
132
    DBUG_RETURN((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
109
133
                                to_length-1) -
110
134
                        (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
111
135
  length= strconvert(system_charset_info, from,
116
140
    memcpy(to + length, "@@@", 4);
117
141
    length+= 3;
118
142
  }
119
 
  return(length);
 
143
  DBUG_PRINT("exit", ("to '%s'", to));
 
144
  DBUG_RETURN(length);
120
145
}
121
146
 
122
147
 
143
168
    'db' is always converted.
144
169
    'ext' is not converted.
145
170
 
146
 
    The conversion suppression is required for ALTER Table. This
 
171
    The conversion suppression is required for ALTER TABLE. This
147
172
    statement creates intermediate tables. These are regular
148
173
    (non-temporary) tables with a temporary name. Their path names must
149
174
    be derivable from the table name. So we cannot use
153
178
    path length
154
179
*/
155
180
 
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)
 
181
uint build_table_filename(char *buff, size_t bufflen, const char *db,
 
182
                          const char *table_name, const char *ext, uint flags)
158
183
{
159
184
  char dbbuff[FN_REFLEN];
160
185
  char tbbuff[FN_REFLEN];
 
186
  DBUG_ENTER("build_table_filename");
 
187
  DBUG_PRINT("enter", ("db: '%s'  table_name: '%s'  ext: '%s'  flags: %x",
 
188
                       db, table_name, ext, flags));
161
189
 
162
190
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
 
    my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
 
191
    strnmov(tbbuff, table_name, sizeof(tbbuff));
164
192
  else
165
 
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
 
193
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
166
194
 
167
 
  tablename_to_filename(db, dbbuff, sizeof(dbbuff));
 
195
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
168
196
 
169
197
  char *end = buff + bufflen;
170
198
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
171
 
  char *pos = my_stpncpy(buff, mysql_data_home, bufflen);
 
199
  char *pos = strnmov(buff, mysql_data_home, bufflen);
172
200
  int rootdir_len= strlen(FN_ROOTDIR);
173
201
  if (pos - rootdir_len >= buff &&
174
202
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
175
 
    pos= my_stpncpy(pos, FN_ROOTDIR, end - pos);
176
 
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NULL);
 
203
    pos= strnmov(pos, FN_ROOTDIR, end - pos);
 
204
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
177
205
#ifdef USE_SYMDIR
178
206
  unpack_dirname(buff, buff);
179
207
  pos= strend(buff);
180
208
#endif
181
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
 
209
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
182
210
 
183
 
  return(pos - buff);
 
211
  DBUG_PRINT("exit", ("buff: '%s'", buff));
 
212
  DBUG_RETURN(pos - buff);
184
213
}
185
214
 
186
215
 
202
231
    path length
203
232
*/
204
233
 
205
 
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
234
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
206
235
{
 
236
  DBUG_ENTER("build_tmptable_filename");
207
237
 
208
 
  char *p= my_stpncpy(buff, mysql_tmpdir, bufflen);
209
 
  snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
 
238
  char *p= strnmov(buff, mysql_tmpdir, bufflen);
 
239
  my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
210
240
              tmp_file_prefix, current_pid,
211
241
              thd->thread_id, thd->tmp_table++, reg_ext);
212
242
 
216
246
    my_casedn_str(files_charset_info, p);
217
247
  }
218
248
 
219
 
  uint32_t length= unpack_filename(buff, buff);
220
 
  return(length);
221
 
}
 
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
  ssize_t io_size= (ssize_t)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
 
222
1176
 
223
1177
/*
224
1178
  SYNOPSIS
273
1227
 
274
1228
*/
275
1229
 
276
 
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
 
1230
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
 
1231
                    my_bool drop_temporary)
277
1232
{
278
1233
  bool error, need_start_waiting= false;
 
1234
  DBUG_ENTER("mysql_rm_table");
279
1235
 
280
1236
  if (tables && tables->schema_table)
281
1237
  {
282
1238
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
283
 
    return(true);
 
1239
    DBUG_RETURN(true);
284
1240
  }
285
1241
 
286
1242
  /* mark for close and remove all cached entries */
289
1245
  {
290
1246
    if (!thd->locked_tables &&
291
1247
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
292
 
      return(true);
 
1248
      DBUG_RETURN(true);
293
1249
  }
294
1250
 
295
1251
  /*
303
1259
    start_waiting_global_read_lock(thd);
304
1260
 
305
1261
  if (error)
306
 
    return(true);
 
1262
    DBUG_RETURN(true);
307
1263
  my_ok(thd);
308
 
  return(false);
 
1264
  DBUG_RETURN(false);
309
1265
}
310
1266
 
311
1267
/*
338
1294
   -1   Thread was killed
339
1295
*/
340
1296
 
341
 
int mysql_rm_table_part2(THD *thd, TableList *tables, bool if_exists,
 
1297
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
342
1298
                         bool drop_temporary, bool drop_view,
343
1299
                         bool dont_log_query)
344
1300
{
345
 
  TableList *table;
 
1301
  TABLE_LIST *table;
346
1302
  char path[FN_REFLEN], *alias;
347
 
  uint32_t path_length;
 
1303
  uint path_length;
348
1304
  String wrong_tables;
349
1305
  int error= 0;
350
1306
  int non_temp_tables_count= 0;
351
1307
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
352
1308
  String built_query;
 
1309
  DBUG_ENTER("mysql_rm_table_part2");
353
1310
 
354
1311
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
355
1312
  {
356
1313
    built_query.set_charset(system_charset_info);
357
1314
    if (if_exists)
358
 
      built_query.append("DROP Table IF EXISTS ");
 
1315
      built_query.append("DROP TABLE IF EXISTS ");
359
1316
    else
360
 
      built_query.append("DROP Table ");
 
1317
      built_query.append("DROP TABLE ");
361
1318
  }
362
1319
 
363
1320
  mysql_ha_rm_tables(thd, tables, false);
381
1338
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
382
1339
  {
383
1340
    pthread_mutex_unlock(&LOCK_open);
384
 
    return(1);
 
1341
    DBUG_RETURN(1);
385
1342
  }
386
1343
 
387
1344
  /* Don't give warnings for not found errors, as we already generate notes */
393
1350
    handlerton *table_type;
394
1351
    enum legacy_db_type frm_db_type;
395
1352
 
 
1353
    DBUG_PRINT("table", ("table_l: '%s'.'%s'  table: 0x%lx  s: 0x%lx",
 
1354
                         table->db, table->table_name, (long) table->table,
 
1355
                         table->table ? (long) table->table->s : (long) -1));
396
1356
 
397
1357
    error= drop_temporary_table(thd, table);
398
1358
 
402
1362
      tmp_table_deleted= 1;
403
1363
      continue;
404
1364
    case -1:
 
1365
      DBUG_ASSERT(thd->in_sub_stmt);
405
1366
      error= 1;
406
1367
      goto err_with_placeholders;
407
1368
    default:
436
1397
    table_type= table->db_type;
437
1398
    if (!drop_temporary)
438
1399
    {
439
 
      Table *locked_table;
 
1400
      TABLE *locked_table;
440
1401
      abort_locked_tables(thd, db, table->table_name);
441
1402
      remove_table_from_cache(thd, db, table->table_name,
442
1403
                              RTFC_WAIT_OTHER_THREAD_FLAG |
461
1422
    }
462
1423
    if (drop_temporary ||
463
1424
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
464
 
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != true)))
 
1425
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
465
1426
    {
466
1427
      // Table was not found on disk and table can't be created from engine
467
1428
      if (if_exists)
468
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1429
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
469
1430
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
470
1431
                            table->table_name);
471
1432
      else
498
1459
      {
499
1460
        int new_error;
500
1461
        /* Delete the table definition file */
501
 
        my_stpcpy(end,reg_ext);
 
1462
        strmov(end,reg_ext);
502
1463
        if (!(new_error=my_delete(path,MYF(MY_WME))))
503
1464
        {
504
1465
          some_tables_deleted=1;
513
1474
        wrong_tables.append(',');
514
1475
      wrong_tables.append(String(table->table_name,system_charset_info));
515
1476
    }
 
1477
    DBUG_PRINT("table", ("table: 0x%lx  s: 0x%lx", (long) table->table,
 
1478
                         table->table ? (long) table->table->s : (long) -1));
516
1479
  }
517
1480
  /*
518
1481
    It's safe to unlock LOCK_open: we have an exclusive lock
527
1490
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
528
1491
                      wrong_tables.c_ptr());
529
1492
    else
530
 
    {
531
1493
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
532
 
    }
533
1494
    error= 1;
534
1495
  }
535
1496
 
581
1542
  }
582
1543
  pthread_mutex_lock(&LOCK_open);
583
1544
err_with_placeholders:
584
 
  unlock_table_names(thd, tables, (TableList*) 0);
 
1545
  unlock_table_names(thd, tables, (TABLE_LIST*) 0);
585
1546
  pthread_mutex_unlock(&LOCK_open);
586
1547
  thd->no_warnings_for_error= 0;
587
 
  return(error);
 
1548
  DBUG_RETURN(error);
588
1549
}
589
1550
 
590
1551
 
604
1565
*/
605
1566
 
606
1567
bool quick_rm_table(handlerton *base,const char *db,
607
 
                    const char *table_name, uint32_t flags)
 
1568
                    const char *table_name, uint flags)
608
1569
{
609
1570
  char path[FN_REFLEN];
610
1571
  bool error= 0;
 
1572
  DBUG_ENTER("quick_rm_table");
611
1573
 
612
 
  uint32_t path_length= build_table_filename(path, sizeof(path),
 
1574
  uint path_length= build_table_filename(path, sizeof(path),
613
1575
                                         db, table_name, reg_ext, flags);
614
1576
  if (my_delete(path,MYF(0)))
615
1577
    error= 1; /* purecov: inspected */
616
1578
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
617
 
  return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
 
1579
  DBUG_RETURN(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
618
1580
              error);
619
1581
}
620
1582
 
685
1647
 
686
1648
bool check_duplicates_in_interval(const char *set_or_name,
687
1649
                                  const char *name, TYPELIB *typelib,
688
 
                                  const CHARSET_INFO * const cs, unsigned int *dup_val_count)
 
1650
                                  CHARSET_INFO *cs, unsigned int *dup_val_count)
689
1651
{
690
1652
  TYPELIB tmp= *typelib;
691
1653
  const char **cur_value= typelib->type_names;
726
1688
  RETURN VALUES
727
1689
    void
728
1690
*/
729
 
void calculate_interval_lengths(const CHARSET_INFO * const cs, TYPELIB *interval,
730
 
                                uint32_t *max_length, uint32_t *tot_length)
 
1691
void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
 
1692
                                uint32 *max_length, uint32 *tot_length)
731
1693
{
732
1694
  const char **pos;
733
 
  uint32_t *len;
 
1695
  uint *len;
734
1696
  *max_length= *tot_length= 0;
735
1697
  for (pos= interval->type_names, len= interval->type_lengths;
736
1698
       *pos ; pos++, len++)
737
1699
  {
738
 
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
 
1700
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
739
1701
    *tot_length+= length;
740
 
    set_if_bigger(*max_length, (uint32_t)length);
 
1702
    set_if_bigger(*max_length, (uint32)length);
741
1703
  }
742
1704
}
743
1705
 
762
1724
*/
763
1725
 
764
1726
int prepare_create_field(Create_field *sql_field, 
765
 
                         uint32_t *blob_columns,
 
1727
                         uint *blob_columns,
766
1728
                         int *timestamps, int *timestamps_with_niladic,
767
 
                         int64_t table_flags __attribute__((unused)))
 
1729
                         longlong table_flags)
768
1730
{
769
1731
  unsigned int dup_val_count;
 
1732
  DBUG_ENTER("prepare_field");
770
1733
 
771
1734
  /*
772
1735
    This code came from mysql_prepare_create_table.
773
1736
    Indent preserved to make patching easier
774
1737
  */
775
 
  assert(sql_field->charset);
 
1738
  DBUG_ASSERT(sql_field->charset);
776
1739
 
777
1740
  switch (sql_field->sql_type) {
778
 
  case DRIZZLE_TYPE_BLOB:
 
1741
  case MYSQL_TYPE_BLOB:
 
1742
  case MYSQL_TYPE_MEDIUM_BLOB:
 
1743
  case MYSQL_TYPE_TINY_BLOB:
 
1744
  case MYSQL_TYPE_LONG_BLOB:
779
1745
    sql_field->pack_flag=FIELDFLAG_BLOB |
780
1746
      pack_length_to_packflag(sql_field->pack_length -
781
1747
                              portable_sizeof_char_ptr);
785
1751
    sql_field->unireg_check=Field::BLOB_FIELD;
786
1752
    (*blob_columns)++;
787
1753
    break;
788
 
  case DRIZZLE_TYPE_VARCHAR:
 
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:
789
1773
    sql_field->pack_flag=0;
790
1774
    if (sql_field->charset->state & MY_CS_BINSORT)
791
1775
      sql_field->pack_flag|=FIELDFLAG_BINARY;
792
1776
    break;
793
 
  case DRIZZLE_TYPE_ENUM:
 
1777
  case MYSQL_TYPE_ENUM:
794
1778
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
795
1779
      FIELDFLAG_INTERVAL;
796
1780
    if (sql_field->charset->state & MY_CS_BINSORT)
799
1783
    if (check_duplicates_in_interval("ENUM",sql_field->field_name,
800
1784
                                 sql_field->interval,
801
1785
                                     sql_field->charset, &dup_val_count))
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:
 
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:
808
1810
    sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
809
1811
    break;
810
 
  case DRIZZLE_TYPE_NEWDECIMAL:
 
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:
811
1819
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
812
1820
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
813
1821
                           FIELDFLAG_DECIMAL) |
814
 
                          (sql_field->flags & DECIMAL_FLAG ?  FIELDFLAG_DECIMAL_POSITION : 0) |
 
1822
                          (sql_field->flags & ZEROFILL_FLAG ?
 
1823
                           FIELDFLAG_ZEROFILL : 0) |
815
1824
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
816
1825
    break;
817
 
  case DRIZZLE_TYPE_TIMESTAMP:
 
1826
  case MYSQL_TYPE_TIMESTAMP:
818
1827
    /* We should replace old TIMESTAMP fields with their newer analogs */
819
1828
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
820
1829
    {
835
1844
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
836
1845
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
837
1846
                           FIELDFLAG_DECIMAL) |
 
1847
                          (sql_field->flags & ZEROFILL_FLAG ?
 
1848
                           FIELDFLAG_ZEROFILL : 0) |
838
1849
                          f_settype((uint) sql_field->sql_type) |
839
1850
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
840
1851
    break;
841
1852
  }
842
 
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
843
 
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
 
1853
  if (!(sql_field->flags & NOT_NULL_FLAG))
844
1854
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
845
1855
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
846
1856
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
847
 
  return(0);
 
1857
  DBUG_RETURN(0);
848
1858
}
849
1859
 
850
1860
/*
877
1887
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
878
1888
                           Alter_info *alter_info,
879
1889
                           bool tmp_table,
880
 
                               uint32_t *db_options,
 
1890
                               uint *db_options,
881
1891
                               handler *file, KEY **key_info_buffer,
882
 
                               uint32_t *key_count, int select_field_count)
 
1892
                               uint *key_count, int select_field_count)
883
1893
{
884
1894
  const char    *key_name;
885
1895
  Create_field  *sql_field,*dup_field;
892
1902
  int           select_field_pos,auto_increment=0;
893
1903
  List_iterator<Create_field> it(alter_info->create_list);
894
1904
  List_iterator<Create_field> it2(alter_info->create_list);
895
 
  uint32_t total_uneven_bit_length= 0;
 
1905
  uint total_uneven_bit_length= 0;
 
1906
  DBUG_ENTER("mysql_prepare_create_table");
896
1907
 
897
1908
  select_field_pos= alter_info->create_list.elements - select_field_count;
898
1909
  null_fields=blob_columns=0;
901
1912
 
902
1913
  for (field_no=0; (sql_field=it++) ; field_no++)
903
1914
  {
904
 
    const CHARSET_INFO *save_cs;
 
1915
    CHARSET_INFO *save_cs;
905
1916
 
906
1917
    /*
907
1918
      Initialize length from its original value (number of characters),
912
1923
    if (!sql_field->charset)
913
1924
      sql_field->charset= create_info->default_table_charset;
914
1925
    /*
915
 
      table_charset is set in ALTER Table if we want change character set
 
1926
      table_charset is set in ALTER TABLE if we want change character set
916
1927
      for all varchar/char columns.
917
1928
      But the table charset must not affect the BLOB fields, so don't
918
1929
      allow to change my_charset_bin to somethig else.
929
1940
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
930
1941
              STRING_WITH_LEN("_bin"));
931
1942
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
932
 
      return(true);
 
1943
      DBUG_RETURN(true);
933
1944
    }
934
1945
 
935
1946
    /*
938
1949
    */
939
1950
    if (sql_field->def && 
940
1951
        save_cs != sql_field->def->collation.collation &&
941
 
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
 
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))
942
1956
    {
943
1957
      /*
944
1958
        Starting from 5.1 we work here with a copy of Create_field
956
1970
      {
957
1971
        /* Could not convert */
958
1972
        my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
959
 
        return(true);
 
1973
        DBUG_RETURN(true);
960
1974
      }
961
1975
    }
962
1976
 
963
 
    if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
 
1977
    if (sql_field->sql_type == MYSQL_TYPE_SET ||
 
1978
        sql_field->sql_type == MYSQL_TYPE_ENUM)
964
1979
    {
965
 
      uint32_t dummy;
966
 
      const CHARSET_INFO * const cs= sql_field->charset;
 
1980
      uint32 dummy;
 
1981
      CHARSET_INFO *cs= sql_field->charset;
967
1982
      TYPELIB *interval= sql_field->interval;
968
1983
 
969
1984
      /*
983
1998
        List_iterator<String> int_it(sql_field->interval_list);
984
1999
        String conv, *tmp;
985
2000
        char comma_buf[4];
986
 
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
987
 
                                          (unsigned char*) comma_buf + 
 
2001
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
 
2002
                                          (uchar*) comma_buf + 
988
2003
                                          sizeof(comma_buf));
989
 
        assert(comma_length > 0);
990
 
        for (uint32_t i= 0; (tmp= int_it++); i++)
 
2004
        DBUG_ASSERT(comma_length > 0);
 
2005
        for (uint i= 0; (tmp= int_it++); i++)
991
2006
        {
992
 
          uint32_t lengthsp;
 
2007
          uint lengthsp;
993
2008
          if (String::needs_conversion(tmp->length(), tmp->charset(),
994
2009
                                       cs, &dummy))
995
2010
          {
996
 
            uint32_t cnv_errs;
 
2011
            uint cnv_errs;
997
2012
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
998
2013
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
999
2014
                                                  conv.length());
1004
2019
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
1005
2020
                                       interval->type_lengths[i]);
1006
2021
          interval->type_lengths[i]= lengthsp;
1007
 
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
 
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
          }
1008
2033
        }
1009
2034
        sql_field->interval_list.empty(); // Don't need interval_list anymore
1010
2035
      }
1011
2036
 
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);
 
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);
1025
2086
            }
1026
2087
 
1027
2088
            /* else, the defaults yield the correct length for NULLs. */
1032
2093
            if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
1033
2094
            {
1034
2095
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1035
 
              return(true);
 
2096
              DBUG_RETURN(true);
1036
2097
            }
1037
2098
          }
1038
2099
        }
1042
2103
      set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
1043
2104
    }
1044
2105
 
 
2106
    if (sql_field->sql_type == MYSQL_TYPE_BIT)
 
2107
    { 
 
2108
      sql_field->pack_flag= FIELDFLAG_NUMBER;
 
2109
      if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
 
2110
        total_uneven_bit_length+= sql_field->length & 7;
 
2111
      else
 
2112
        sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
 
2113
    }
 
2114
 
1045
2115
    sql_field->create_length_to_internal_length();
1046
2116
    if (prepare_blob_field(thd, sql_field))
1047
 
      return(true);
 
2117
      DBUG_RETURN(true);
1048
2118
 
1049
2119
    if (!(sql_field->flags & NOT_NULL_FLAG))
1050
2120
      null_fields++;
1052
2122
    if (check_column_name(sql_field->field_name))
1053
2123
    {
1054
2124
      my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
1055
 
      return(true);
 
2125
      DBUG_RETURN(true);
1056
2126
    }
1057
2127
 
1058
2128
    /* Check if we have used the same field name before */
1069
2139
        if (field_no < select_field_pos || dup_no >= select_field_pos)
1070
2140
        {
1071
2141
          my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
1072
 
          return(true);
 
2142
          DBUG_RETURN(true);
1073
2143
        }
1074
2144
        else
1075
2145
        {
1094
2164
            null_fields--;
1095
2165
          sql_field->flags=             dup_field->flags;
1096
2166
          sql_field->interval=          dup_field->interval;
1097
 
          sql_field->vcol_info=         dup_field->vcol_info;
1098
 
          sql_field->is_stored=      dup_field->is_stored;
1099
2167
          it2.remove();                 // Remove first (create) definition
1100
2168
          select_field_pos--;
1101
2169
          break;
1104
2172
    }
1105
2173
    /* Don't pack rows in old tables if the user has requested this */
1106
2174
    if ((sql_field->flags & BLOB_FLAG) ||
1107
 
        (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
2175
        (sql_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
1108
2176
      (*db_options)|= HA_OPTION_PACK_RECORD;
1109
2177
    it2.rewind();
1110
2178
  }
1116
2184
  it.rewind();
1117
2185
  while ((sql_field=it++))
1118
2186
  {
1119
 
    assert(sql_field->charset != 0);
 
2187
    DBUG_ASSERT(sql_field->charset != 0);
1120
2188
 
1121
2189
    if (prepare_create_field(sql_field, &blob_columns, 
1122
2190
                             &timestamps, &timestamps_with_niladic,
1123
2191
                             file->ha_table_flags()))
1124
 
      return(true);
1125
 
    if (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
 
2192
      DBUG_RETURN(true);
 
2193
    if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
1126
2194
      create_info->varchar= true;
1127
2195
    sql_field->offset= record_offset;
1128
2196
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1129
2197
      auto_increment++;
1130
 
    /*
1131
 
          For now skip fields that are not physically stored in the database
1132
 
          (virtual fields) and update their offset later 
1133
 
          (see the next loop).
1134
 
        */
1135
 
    if (sql_field->is_stored)
1136
 
      record_offset+= sql_field->pack_length;
1137
 
  }
1138
 
  /* Update virtual fields' offset */
1139
 
  it.rewind();
1140
 
  while ((sql_field=it++))
1141
 
  {
1142
 
    if (not sql_field->is_stored)
1143
 
    {
1144
 
      sql_field->offset= record_offset;
1145
 
      record_offset+= sql_field->pack_length;
1146
 
    }
 
2198
    record_offset+= sql_field->pack_length;
1147
2199
  }
1148
2200
  if (timestamps_with_niladic > 1)
1149
2201
  {
1150
2202
    my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
1151
2203
               ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
1152
 
    return(true);
 
2204
    DBUG_RETURN(true);
1153
2205
  }
1154
2206
  if (auto_increment > 1)
1155
2207
  {
1156
2208
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1157
 
    return(true);
 
2209
    DBUG_RETURN(true);
1158
2210
  }
1159
2211
  if (auto_increment &&
1160
2212
      (file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
1161
2213
  {
1162
2214
    my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
1163
2215
               ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
1164
 
    return(true);
 
2216
    DBUG_RETURN(true);
1165
2217
  }
1166
2218
 
1167
2219
  if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
1168
2220
  {
1169
2221
    my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
1170
2222
               MYF(0));
1171
 
    return(true);
 
2223
    DBUG_RETURN(true);
1172
2224
  }
1173
2225
 
1174
2226
  /* Create keys */
1175
2227
 
1176
2228
  List_iterator<Key> key_iterator(alter_info->key_list);
1177
2229
  List_iterator<Key> key_iterator2(alter_info->key_list);
1178
 
  uint32_t key_parts=0, fk_key_count=0;
 
2230
  uint key_parts=0, fk_key_count=0;
1179
2231
  bool primary_key=0,unique_key=0;
1180
2232
  Key *key, *key2;
1181
 
  uint32_t tmp, key_number;
 
2233
  uint tmp, key_number;
1182
2234
  /* special marker for keys to be ignored */
1183
2235
  static char ignore_key[1];
1184
2236
 
1187
2239
 
1188
2240
  while ((key=key_iterator++))
1189
2241
  {
 
2242
    DBUG_PRINT("info", ("key name: '%s'  type: %d", key->name.str ? key->name.str :
 
2243
                        "(none)" , key->type));
1190
2244
    if (key->type == Key::FOREIGN_KEY)
1191
2245
    {
1192
2246
      fk_key_count++;
1193
 
      if (((Foreign_key *)key)->validate(alter_info->create_list))
1194
 
        return true;
1195
2247
      Foreign_key *fk_key= (Foreign_key*) key;
1196
2248
      if (fk_key->ref_columns.elements &&
1197
2249
          fk_key->ref_columns.elements != fk_key->columns.elements)
1200
2252
                 (fk_key->name.str ? fk_key->name.str :
1201
2253
                                     "foreign key without name"),
1202
2254
                 ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
1203
 
        return(true);
 
2255
        DBUG_RETURN(true);
1204
2256
      }
1205
2257
      continue;
1206
2258
    }
1209
2261
    if (key->columns.elements > tmp)
1210
2262
    {
1211
2263
      my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
1212
 
      return(true);
 
2264
      DBUG_RETURN(true);
1213
2265
    }
1214
2266
    if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))
1215
 
      return(true);
 
2267
      DBUG_RETURN(true);
1216
2268
    key_iterator2.rewind ();
1217
2269
    if (key->type != Key::FOREIGN_KEY)
1218
2270
    {
1251
2303
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
1252
2304
    {
1253
2305
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1254
 
      return(true);
 
2306
      DBUG_RETURN(true);
1255
2307
    }
1256
2308
  }
1257
2309
  tmp=file->max_keys();
1258
2310
  if (*key_count > tmp)
1259
2311
  {
1260
2312
    my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
1261
 
    return(true);
 
2313
    DBUG_RETURN(true);
1262
2314
  }
1263
2315
 
1264
2316
  (*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));
1265
2317
  key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
1266
2318
  if (!*key_info_buffer || ! key_part_info)
1267
 
    return(true);                               // Out of memory
 
2319
    DBUG_RETURN(true);                          // Out of memory
1268
2320
 
1269
2321
  key_iterator.rewind();
1270
2322
  key_number=0;
1271
2323
  for (; (key=key_iterator++) ; key_number++)
1272
2324
  {
1273
 
    uint32_t key_length=0;
 
2325
    uint key_length=0;
1274
2326
    Key_part_spec *column;
1275
2327
 
1276
2328
    if (key->name.str == ignore_key)
1297
2349
    if (key->generated)
1298
2350
      key_info->flags|= HA_GENERATED_KEY;
1299
2351
 
1300
 
    key_info->key_parts=(uint8_t) key->columns.elements;
 
2352
    key_info->key_parts=(uint8) key->columns.elements;
1301
2353
    key_info->key_part=key_part_info;
1302
2354
    key_info->usable_key_parts= key_number;
1303
2355
    key_info->algorithm= key->key_create_info.algorithm;
1314
2366
    if (key_info->block_size)
1315
2367
      key_info->flags|= HA_USES_BLOCK_SIZE;
1316
2368
 
1317
 
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
2369
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
1318
2370
                                           key->key_create_info.comment.str,
1319
2371
                                           key->key_create_info.comment.str +
1320
2372
                                           key->key_create_info.comment.length,
1325
2377
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
1326
2378
               key->key_create_info.comment.str,"INDEX COMMENT",
1327
2379
               (uint) INDEX_COMMENT_MAXLEN);
1328
 
      return(-1);
 
2380
      DBUG_RETURN(-1);
1329
2381
    }
1330
2382
 
1331
2383
    key_info->comment.length= key->key_create_info.comment.length;
1336
2388
    }
1337
2389
 
1338
2390
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
1339
 
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
 
2391
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
1340
2392
    {
1341
 
      uint32_t length;
 
2393
      uint length;
1342
2394
      Key_part_spec *dup_column;
1343
2395
 
1344
2396
      it.rewind();
1351
2403
      if (!sql_field)
1352
2404
      {
1353
2405
        my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
1354
 
        return(true);
 
2406
        DBUG_RETURN(true);
1355
2407
      }
1356
2408
      while ((dup_column= cols2++) != column)
1357
2409
      {
1361
2413
          my_printf_error(ER_DUP_FIELDNAME,
1362
2414
                          ER(ER_DUP_FIELDNAME),MYF(0),
1363
2415
                          column->field_name.str);
1364
 
          return(true);
 
2416
          DBUG_RETURN(true);
1365
2417
        }
1366
2418
      }
1367
2419
      cols2.rewind();
1373
2425
          if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
1374
2426
          {
1375
2427
            my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
1376
 
            return(true);
 
2428
            DBUG_RETURN(true);
1377
2429
          }
1378
2430
          if (!column->length)
1379
2431
          {
1380
2432
            my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
1381
 
            return(true);
 
2433
            DBUG_RETURN(true);
1382
2434
          }
1383
2435
        }
1384
 
        if (not sql_field->is_stored)
1385
 
        {
1386
 
          /* Key fields must always be physically stored. */
1387
 
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
1388
 
          return(true);
1389
 
        }
1390
 
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
1391
 
        {
1392
 
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
1393
 
          return(true);
1394
 
        }
1395
2436
        if (!(sql_field->flags & NOT_NULL_FLAG))
1396
2437
        {
1397
2438
          if (key->type == Key::PRIMARY)
1407
2448
            if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
1408
2449
            {
1409
2450
              my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
1410
 
              return(true);
 
2451
              DBUG_RETURN(true);
1411
2452
            }
1412
2453
          }
1413
2454
        }
1419
2460
      }
1420
2461
 
1421
2462
      key_part_info->fieldnr= field;
1422
 
      key_part_info->offset=  (uint16_t) sql_field->offset;
 
2463
      key_part_info->offset=  (uint16) sql_field->offset;
1423
2464
      key_part_info->key_type=sql_field->pack_flag;
1424
2465
      length= sql_field->key_length;
1425
2466
 
1430
2471
          if ((length=column->length) > max_key_length ||
1431
2472
              length > file->max_key_part_length())
1432
2473
          {
1433
 
            length=cmin(max_key_length, file->max_key_part_length());
 
2474
            length=min(max_key_length, file->max_key_part_length());
1434
2475
            if (key->type == Key::MULTIPLE)
1435
2476
            {
1436
2477
              /* not a critical problem */
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,
 
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,
1441
2482
                           ER_TOO_LONG_KEY, warn_buff);
1442
2483
              /* Align key length to multibyte char boundary */
1443
2484
              length-= length % sql_field->charset->mbmaxlen;
1445
2486
            else
1446
2487
            {
1447
2488
              my_error(ER_TOO_LONG_KEY,MYF(0),length);
1448
 
              return(true);
 
2489
              DBUG_RETURN(true);
1449
2490
            }
1450
2491
          }
1451
2492
        }
1457
2498
                    column->length != length)))
1458
2499
        {
1459
2500
          my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
1460
 
          return(true);
 
2501
          DBUG_RETURN(true);
1461
2502
        }
1462
2503
        else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
1463
2504
          length=column->length;
1465
2506
      else if (length == 0)
1466
2507
      {
1467
2508
        my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
1468
 
          return(true);
 
2509
          DBUG_RETURN(true);
1469
2510
      }
1470
2511
      if (length > file->max_key_part_length())
1471
2512
      {
1473
2514
        if (key->type == Key::MULTIPLE)
1474
2515
        {
1475
2516
          /* not a critical problem */
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,
 
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,
1480
2521
                       ER_TOO_LONG_KEY, warn_buff);
1481
2522
          /* Align key length to multibyte char boundary */
1482
2523
          length-= length % sql_field->charset->mbmaxlen;
1484
2525
        else
1485
2526
        {
1486
2527
          my_error(ER_TOO_LONG_KEY,MYF(0),length);
1487
 
          return(true);
 
2528
          DBUG_RETURN(true);
1488
2529
        }
1489
2530
      }
1490
 
      key_part_info->length=(uint16_t) length;
 
2531
      key_part_info->length=(uint16) length;
1491
2532
      /* Use packed keys for long strings on the first column */
1492
2533
      if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
1493
2534
          (length >= KEY_DEFAULT_PACK_LENGTH &&
1494
 
           (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
 
2535
           (sql_field->sql_type == MYSQL_TYPE_STRING ||
 
2536
            sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
1495
2537
            sql_field->pack_flag & FIELDFLAG_BLOB)))
1496
2538
      {
1497
2539
        if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
1498
 
            sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
 
2540
            sql_field->sql_type == MYSQL_TYPE_VARCHAR)
1499
2541
          key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
1500
2542
        else
1501
2543
          key_info->flags|= HA_PACK_KEY;
1516
2558
          {
1517
2559
            my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
1518
2560
                       MYF(0));
1519
 
            return(true);
 
2561
            DBUG_RETURN(true);
1520
2562
          }
1521
2563
          key_name=primary_key_name;
1522
2564
          primary_key=1;
1527
2569
        if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
1528
2570
        {
1529
2571
          my_error(ER_DUP_KEYNAME, MYF(0), key_name);
1530
 
          return(true);
 
2572
          DBUG_RETURN(true);
1531
2573
        }
1532
2574
        key_info->name=(char*) key_name;
1533
2575
      }
1535
2577
    if (!key_info->name || check_column_name(key_info->name))
1536
2578
    {
1537
2579
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1538
 
      return(true);
 
2580
      DBUG_RETURN(true);
1539
2581
    }
1540
2582
    if (!(key_info->flags & HA_NULL_PART_KEY))
1541
2583
      unique_key=1;
1542
 
    key_info->key_length=(uint16_t) key_length;
 
2584
    key_info->key_length=(uint16) key_length;
1543
2585
    if (key_length > max_key_length)
1544
2586
    {
1545
2587
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1546
 
      return(true);
 
2588
      DBUG_RETURN(true);
1547
2589
    }
1548
2590
    key_info++;
1549
2591
  }
1551
2593
      (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
1552
2594
  {
1553
2595
    my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1554
 
    return(true);
 
2596
    DBUG_RETURN(true);
1555
2597
  }
1556
2598
  if (auto_increment > 0)
1557
2599
  {
1558
2600
    my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1559
 
    return(true);
 
2601
    DBUG_RETURN(true);
1560
2602
  }
1561
2603
  /* Sort keys in optimized order */
1562
 
  my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
 
2604
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
1563
2605
           (qsort_cmp) sort_keys);
1564
2606
  create_info->null_bits= null_fields;
1565
2607
 
1571
2613
 
1572
2614
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
1573
2615
        !sql_field->def &&
1574
 
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
 
2616
        sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
1575
2617
        (sql_field->flags & NOT_NULL_FLAG) &&
1576
2618
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1577
2619
    {
1590
2632
      */
1591
2633
 
1592
2634
      my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1593
 
      return(true);
 
2635
      DBUG_RETURN(true);
1594
2636
    }
1595
2637
  }
1596
2638
 
1597
 
  return(false);
 
2639
  DBUG_RETURN(false);
1598
2640
}
1599
2641
 
1600
2642
 
1643
2685
        In this case the error is given
1644
2686
*/
1645
2687
 
1646
 
static bool prepare_blob_field(THD *thd __attribute__((unused)),
1647
 
                               Create_field *sql_field)
 
2688
static bool prepare_blob_field(THD *thd, Create_field *sql_field)
1648
2689
{
 
2690
  DBUG_ENTER("prepare_blob_field");
1649
2691
 
1650
2692
  if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
1651
2693
      !(sql_field->flags & BLOB_FLAG))
1652
2694
  {
1653
2695
    my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
1654
2696
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1655
 
    return(1);
 
2697
    DBUG_RETURN(1);
1656
2698
  }
1657
2699
    
1658
2700
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1659
2701
  {
1660
 
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
 
2702
    if (sql_field->sql_type == MYSQL_TYPE_BLOB)
1661
2703
    {
1662
2704
      /* The user has given a length to the blob column */
1663
2705
      sql_field->sql_type= get_blob_type_from_length(sql_field->length);
1665
2707
    }
1666
2708
    sql_field->length= 0;
1667
2709
  }
1668
 
  return(0);
 
2710
  DBUG_RETURN(0);
1669
2711
}
1670
2712
 
1671
2713
 
1686
2728
 
1687
2729
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
1688
2730
{
1689
 
  if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
 
2731
  if (sql_field->sql_type == MYSQL_TYPE_SET ||
 
2732
      sql_field->sql_type == MYSQL_TYPE_ENUM)
1690
2733
  {
1691
 
    uint32_t field_length, dummy;
1692
 
    /* DRIZZLE_TYPE_ENUM */
 
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 */
1693
2744
    {
1694
2745
      calculate_interval_lengths(sql_field->charset,
1695
2746
                                 sql_field->interval,
1699
2750
    set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
1700
2751
  }
1701
2752
 
 
2753
  if (sql_field->sql_type == MYSQL_TYPE_BIT)
 
2754
  {
 
2755
    sql_field->pack_flag= FIELDFLAG_NUMBER |
 
2756
                          FIELDFLAG_TREAT_BIT_AS_CHAR;
 
2757
  }
1702
2758
  sql_field->create_length_to_internal_length();
1703
 
  assert(sql_field->def == 0);
 
2759
  DBUG_ASSERT(sql_field->def == 0);
1704
2760
  /* Can't go wrong as sql_field->def is not defined */
1705
2761
  (void) prepare_blob_field(thd, sql_field);
1706
2762
}
1718
2774
    fields              List of fields to create
1719
2775
    keys                List of keys to create
1720
2776
    internal_tmp_table  Set to 1 if this is an internal temporary table
1721
 
                        (From ALTER Table)
 
2777
                        (From ALTER TABLE)
1722
2778
    select_field_count  
1723
2779
 
1724
2780
  DESCRIPTION
1744
2800
                                HA_CREATE_INFO *create_info,
1745
2801
                                Alter_info *alter_info,
1746
2802
                                bool internal_tmp_table,
1747
 
                                uint32_t select_field_count,
1748
 
                                bool lock_open_lock)
 
2803
                                uint select_field_count)
1749
2804
{
1750
2805
  char          path[FN_REFLEN];
1751
 
  uint32_t          path_length;
 
2806
  uint          path_length;
1752
2807
  const char    *alias;
1753
2808
  uint          db_options, key_count;
1754
2809
  KEY           *key_info_buffer;
1755
2810
  handler       *file;
1756
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
 
1757
2817
  /* Check for duplicate fields and check type of table to create */
1758
2818
  if (!alter_info->create_list.elements)
1759
2819
  {
1760
2820
    my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1761
2821
               MYF(0));
1762
 
    return(true);
 
2822
    DBUG_RETURN(true);
1763
2823
  }
1764
2824
  if (check_engine(thd, table_name, create_info))
1765
 
    return(true);
 
2825
    DBUG_RETURN(true);
1766
2826
  db_options= create_info->table_options;
1767
2827
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1768
2828
    db_options|=HA_OPTION_PACK_RECORD;
1771
2831
                              create_info->db_type)))
1772
2832
  {
1773
2833
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1774
 
    return(true);
 
2834
    DBUG_RETURN(true);
1775
2835
  }
1776
2836
 
1777
2837
  set_table_default_charset(thd, create_info, (char*) db);
1796
2856
    if (strchr(alias, FN_DEVCHAR))
1797
2857
    {
1798
2858
      my_error(ER_WRONG_TABLE_NAME, MYF(0), alias);
1799
 
      return(true);
 
2859
      DBUG_RETURN(true);
1800
2860
    }
1801
2861
#endif
1802
2862
    path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
1810
2870
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1811
2871
    {
1812
2872
      create_info->table_existed= 1;            // Mark that table existed
1813
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2873
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1814
2874
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1815
2875
                          alias);
1816
2876
      error= 0;
1820
2880
    goto err;
1821
2881
  }
1822
2882
 
1823
 
  if (lock_open_lock)
1824
 
    pthread_mutex_lock(&LOCK_open);
 
2883
  VOID(pthread_mutex_lock(&LOCK_open));
1825
2884
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1826
2885
  {
1827
2886
    if (!access(path,F_OK))
1860
2919
    bool create_if_not_exists =
1861
2920
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1862
2921
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
 
2922
    DBUG_PRINT("info", ("exists_in_engine: %u",retcode));
1863
2923
    switch (retcode)
1864
2924
    {
1865
2925
      case HA_ERR_NO_SUCH_TABLE:
1866
2926
        /* Normal case, no table exists. we can go and create it */
1867
2927
        break;
1868
2928
      case HA_ERR_TABLE_EXIST:
 
2929
        DBUG_PRINT("info", ("Table existed in handler"));
1869
2930
 
1870
2931
      if (create_if_not_exists)
1871
2932
        goto warn;
1873
2934
      goto unlock_and_end;
1874
2935
        break;
1875
2936
      default:
 
2937
        DBUG_PRINT("info", ("error: %u from storage engine", retcode));
1876
2938
        my_error(retcode, MYF(0),table_name);
1877
2939
        goto unlock_and_end;
1878
2940
    }
1879
2941
  }
1880
2942
 
1881
 
  thd->set_proc_info("creating table");
 
2943
  thd_proc_info(thd, "creating table");
1882
2944
  create_info->table_existed= 0;                // Mark that table is created
1883
2945
 
1884
2946
#ifdef HAVE_READLINK
1897
2959
#endif /* HAVE_READLINK */
1898
2960
  {
1899
2961
    if (create_info->data_file_name)
1900
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
2962
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
1901
2963
                   "DATA DIRECTORY option ignored");
1902
2964
    if (create_info->index_file_name)
1903
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
2965
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
1904
2966
                   "INDEX DIRECTORY option ignored");
1905
2967
    create_info->data_file_name= create_info->index_file_name= 0;
1906
2968
  }
1937
2999
    write_bin_log(thd, true, thd->query, thd->query_length);
1938
3000
  error= false;
1939
3001
unlock_and_end:
1940
 
  if (lock_open_lock)
1941
 
    pthread_mutex_unlock(&LOCK_open);
 
3002
  VOID(pthread_mutex_unlock(&LOCK_open));
1942
3003
 
1943
3004
err:
1944
 
  thd->set_proc_info("After create");
 
3005
  thd_proc_info(thd, "After create");
1945
3006
  delete file;
1946
 
  return(error);
 
3007
  DBUG_RETURN(error);
1947
3008
 
1948
3009
warn:
1949
3010
  error= false;
1950
 
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3011
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1951
3012
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1952
3013
                      alias);
1953
3014
  create_info->table_existed= 1;                // Mark that table existed
1963
3024
                        HA_CREATE_INFO *create_info,
1964
3025
                        Alter_info *alter_info,
1965
3026
                        bool internal_tmp_table,
1966
 
                        uint32_t select_field_count)
 
3027
                        uint select_field_count)
1967
3028
{
1968
 
  Table *name_lock= 0;
 
3029
  TABLE *name_lock= 0;
1969
3030
  bool result;
 
3031
  DBUG_ENTER("mysql_create_table");
1970
3032
 
1971
3033
  /* Wait for any database locks */
1972
3034
  pthread_mutex_lock(&LOCK_lock_db);
1973
3035
  while (!thd->killed &&
1974
 
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
 
3036
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
1975
3037
  {
1976
3038
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1977
3039
    pthread_mutex_lock(&LOCK_lock_db);
1980
3042
  if (thd->killed)
1981
3043
  {
1982
3044
    pthread_mutex_unlock(&LOCK_lock_db);
1983
 
    return(true);
 
3045
    DBUG_RETURN(true);
1984
3046
  }
1985
3047
  creating_table++;
1986
3048
  pthread_mutex_unlock(&LOCK_lock_db);
1996
3058
    {
1997
3059
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1998
3060
      {
1999
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3061
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
2000
3062
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
2001
3063
                            table_name);
2002
3064
        create_info->table_existed= 1;
2014
3076
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
2015
3077
                                     alter_info,
2016
3078
                                     internal_tmp_table,
2017
 
                                     select_field_count, true);
 
3079
                                     select_field_count);
2018
3080
 
2019
3081
unlock:
2020
3082
  if (name_lock)
2027
3089
  if (!--creating_table && creating_database)
2028
3090
    pthread_cond_signal(&COND_refresh);
2029
3091
  pthread_mutex_unlock(&LOCK_lock_db);
2030
 
  return(result);
 
3092
  DBUG_RETURN(result);
2031
3093
}
2032
3094
 
2033
3095
 
2059
3121
    Only 3 chars + '\0' left, so need to limit to 2 digit
2060
3122
    This is ok as we can't have more than 100 keys anyway
2061
3123
  */
2062
 
  for (uint32_t i=2 ; i< 100; i++)
 
3124
  for (uint i=2 ; i< 100; i++)
2063
3125
  {
2064
3126
    *buff_end= '_';
2065
3127
    int10_to_str(i, buff_end+1, 10);
2099
3161
bool
2100
3162
mysql_rename_table(handlerton *base, const char *old_db,
2101
3163
                   const char *old_name, const char *new_db,
2102
 
                   const char *new_name, uint32_t flags)
 
3164
                   const char *new_name, uint flags)
2103
3165
{
2104
3166
  THD *thd= current_thd;
2105
3167
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2107
3169
  char tmp_name[NAME_LEN+1];
2108
3170
  handler *file;
2109
3171
  int error=0;
 
3172
  DBUG_ENTER("mysql_rename_table");
 
3173
  DBUG_PRINT("enter", ("old: '%s'.'%s'  new: '%s'.'%s'",
 
3174
                       old_db, old_name, new_db, new_name));
2110
3175
 
2111
3176
  file= (base == NULL ? 0 :
2112
3177
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
2124
3189
  if (lower_case_table_names == 2 && file &&
2125
3190
      !(file->ha_table_flags() & HA_FILE_BASED))
2126
3191
  {
2127
 
    my_stpcpy(tmp_name, old_name);
 
3192
    strmov(tmp_name, old_name);
2128
3193
    my_casedn_str(files_charset_info, tmp_name);
2129
3194
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2130
3195
                         flags & FN_FROM_IS_TMP);
2131
3196
    from_base= lc_from;
2132
3197
 
2133
 
    my_stpcpy(tmp_name, new_name);
 
3198
    strmov(tmp_name, new_name);
2134
3199
    my_casedn_str(files_charset_info, tmp_name);
2135
3200
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2136
3201
                         flags & FN_TO_IS_TMP);
2148
3213
  }
2149
3214
  delete file;
2150
3215
  if (error == HA_ERR_WRONG_COMMAND)
2151
 
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
 
3216
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
2152
3217
  else if (error)
2153
3218
    my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
2154
 
  return(error != 0);
 
3219
  DBUG_RETURN(error != 0);
2155
3220
}
2156
3221
 
2157
3222
 
2174
3239
    Win32 clients must also have a WRITE LOCK on the table !
2175
3240
*/
2176
3241
 
2177
 
void wait_while_table_is_used(THD *thd, Table *table,
 
3242
void wait_while_table_is_used(THD *thd, TABLE *table,
2178
3243
                              enum ha_extra_function function)
2179
3244
{
 
3245
  DBUG_ENTER("wait_while_table_is_used");
 
3246
  DBUG_PRINT("enter", ("table: '%s'  share: 0x%lx  db_stat: %u  version: %lu",
 
3247
                       table->s->table_name.str, (ulong) table->s,
 
3248
                       table->db_stat, table->s->version));
2180
3249
 
2181
3250
  safe_mutex_assert_owner(&LOCK_open);
2182
3251
 
2183
 
  table->file->extra(function);
 
3252
  VOID(table->file->extra(function));
2184
3253
  /* Mark all tables that are in use as 'old' */
2185
3254
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
2186
3255
 
2188
3257
  remove_table_from_cache(thd, table->s->db.str,
2189
3258
                          table->s->table_name.str,
2190
3259
                          RTFC_WAIT_OTHER_THREAD_FLAG);
2191
 
  return;
 
3260
  DBUG_VOID_RETURN;
2192
3261
}
2193
3262
 
2194
3263
/*
2208
3277
    Win32 clients must also have a WRITE LOCK on the table !
2209
3278
*/
2210
3279
 
2211
 
void close_cached_table(THD *thd, Table *table)
 
3280
void close_cached_table(THD *thd, TABLE *table)
2212
3281
{
 
3282
  DBUG_ENTER("close_cached_table");
2213
3283
 
2214
3284
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
2215
3285
  /* Close lock if this is not got with LOCK TABLES */
2223
3293
 
2224
3294
  /* When lock on LOCK_open is freed other threads can continue */
2225
3295
  broadcast_refresh();
2226
 
  return;
 
3296
  DBUG_VOID_RETURN;
2227
3297
}
2228
3298
 
2229
 
static int send_check_errmsg(THD *thd, TableList* table,
 
3299
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
2230
3300
                             const char* operator_name, const char* errmsg)
2231
3301
 
2232
3302
{
2243
3313
}
2244
3314
 
2245
3315
 
2246
 
static int prepare_for_repair(THD *thd, TableList *table_list,
 
3316
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
2247
3317
                              HA_CHECK_OPT *check_opt)
2248
3318
{
2249
3319
  int error= 0;
2250
 
  Table tmp_table, *table;
 
3320
  TABLE tmp_table, *table;
2251
3321
  TABLE_SHARE *share;
2252
3322
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
2253
3323
  const char **ext;
2254
3324
  struct stat stat_info;
 
3325
  DBUG_ENTER("prepare_for_repair");
2255
3326
 
2256
3327
  if (!(check_opt->sql_flags & TT_USEFRM))
2257
 
    return(0);
 
3328
    DBUG_RETURN(0);
2258
3329
 
2259
3330
  if (!(table= table_list->table))              /* if open_ltable failed */
2260
3331
  {
2261
3332
    char key[MAX_DBKEY_LENGTH];
2262
 
    uint32_t key_length;
 
3333
    uint key_length;
2263
3334
 
2264
3335
    key_length= create_table_def_key(thd, key, table_list, 0);
2265
3336
    pthread_mutex_lock(&LOCK_open);
2267
3338
                                  &error))))
2268
3339
    {
2269
3340
      pthread_mutex_unlock(&LOCK_open);
2270
 
      return(0);                                // Can't open frm file
 
3341
      DBUG_RETURN(0);                           // Can't open frm file
2271
3342
    }
2272
3343
 
2273
3344
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2274
3345
    {
2275
3346
      release_table_share(share, RELEASE_NORMAL);
2276
3347
      pthread_mutex_unlock(&LOCK_open);
2277
 
      return(0);                           // Out of memory
 
3348
      DBUG_RETURN(0);                           // Out of memory
2278
3349
    }
2279
3350
    table= &tmp_table;
2280
3351
    pthread_mutex_unlock(&LOCK_open);
2281
3352
  }
2282
3353
 
2283
3354
  /*
2284
 
    REPAIR Table ... USE_FRM for temporary tables makes little sense.
 
3355
    REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
2285
3356
  */
2286
3357
  if (table->s->tmp_table)
2287
3358
  {
2311
3382
    goto end;                                   // No data file
2312
3383
 
2313
3384
  // Name of data file
2314
 
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
 
3385
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
2315
3386
  if (stat(from, &stat_info))
2316
3387
    goto end;                           // Can't use USE_FRM flag
2317
3388
 
2318
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2319
 
           from, current_pid, thd->thread_id);
 
3389
  my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
 
3390
              from, current_pid, thd->thread_id);
2320
3391
 
2321
3392
  /* If we could open the table, close it */
2322
3393
  if (table_list->table)
2380
3451
    closefrm(table, 1);                         // Free allocated memory
2381
3452
    pthread_mutex_unlock(&LOCK_open);
2382
3453
  }
2383
 
  return(error);
 
3454
  DBUG_RETURN(error);
2384
3455
}
2385
3456
 
2386
3457
 
2391
3462
    true  Message should be sent by caller 
2392
3463
          (admin operation or network communication failed)
2393
3464
*/
2394
 
static bool mysql_admin_table(THD* thd, TableList* tables,
 
3465
static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
2395
3466
                              HA_CHECK_OPT* check_opt,
2396
3467
                              const char *operator_name,
2397
3468
                              thr_lock_type lock_type,
2398
3469
                              bool open_for_modify,
2399
3470
                              bool no_warnings_for_error,
2400
 
                              uint32_t extra_open_options,
2401
 
                              int (*prepare_func)(THD *, TableList *,
 
3471
                              uint extra_open_options,
 
3472
                              int (*prepare_func)(THD *, TABLE_LIST *,
2402
3473
                                                  HA_CHECK_OPT *),
2403
3474
                              int (handler::*operator_func)(THD *,
2404
3475
                                                            HA_CHECK_OPT *))
2405
3476
{
2406
 
  TableList *table;
 
3477
  TABLE_LIST *table;
2407
3478
  SELECT_LEX *select= &thd->lex->select_lex;
2408
3479
  List<Item> field_list;
2409
3480
  Item *item;
2410
3481
  Protocol *protocol= thd->protocol;
2411
3482
  LEX *lex= thd->lex;
2412
3483
  int result_code= 0;
2413
 
  const CHARSET_INFO * const cs= system_charset_info;
 
3484
  CHARSET_INFO *cs= system_charset_info;
 
3485
  DBUG_ENTER("mysql_admin_table");
2414
3486
 
2415
3487
  if (end_active_trans(thd))
2416
 
    return(1);
 
3488
    DBUG_RETURN(1);
2417
3489
  field_list.push_back(item = new Item_empty_string("Table",
2418
3490
                                                    NAME_CHAR_LEN * 2,
2419
3491
                                                    cs));
2426
3498
  item->maybe_null = 1;
2427
3499
  if (protocol->send_fields(&field_list,
2428
3500
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2429
 
    return(true);
 
3501
    DBUG_RETURN(true);
2430
3502
 
2431
3503
  mysql_ha_rm_tables(thd, tables, false);
2432
3504
 
2436
3508
    char* db = table->db;
2437
3509
    bool fatal_error=0;
2438
3510
 
2439
 
    strxmov(table_name, db, ".", table->table_name, NULL);
 
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);
2440
3514
    thd->open_options|= extra_open_options;
2441
3515
    table->lock_type= lock_type;
2442
3516
    /* open only one table from local list of command */
2443
3517
    {
2444
 
      TableList *save_next_global, *save_next_local;
 
3518
      TABLE_LIST *save_next_global, *save_next_local;
2445
3519
      save_next_global= table->next_global;
2446
3520
      table->next_global= 0;
2447
3521
      save_next_local= table->next_local;
2448
3522
      table->next_local= 0;
2449
 
      select->table_list.first= (unsigned char*)table;
 
3523
      select->table_list.first= (uchar*)table;
2450
3524
      /*
2451
3525
        Time zone tables and SP tables can be add to lex->query_tables list,
2452
3526
        so it have to be prepared.
2457
3531
      lex->query_tables_last= &table->next_global;
2458
3532
      lex->query_tables_own_last= 0;
2459
3533
      thd->no_warnings_for_error= no_warnings_for_error;
 
3534
      table->required_type=FRMTYPE_TABLE;
2460
3535
 
2461
3536
      open_and_lock_tables(thd, table);
2462
3537
      thd->no_warnings_for_error= 0;
2464
3539
      table->next_local= save_next_local;
2465
3540
      thd->open_options&= ~extra_open_options;
2466
3541
    }
 
3542
    DBUG_PRINT("admin", ("table: 0x%lx", (long) table->table));
2467
3543
 
2468
3544
    if (prepare_func)
2469
3545
    {
 
3546
      DBUG_PRINT("admin", ("calling prepare_func"));
2470
3547
      switch ((*prepare_func)(thd, table, check_opt)) {
2471
3548
      case  1:           // error, message written to net
2472
3549
        ha_autocommit_or_rollback(thd, 1);
2473
3550
        end_trans(thd, ROLLBACK);
2474
3551
        close_thread_tables(thd);
 
3552
        DBUG_PRINT("admin", ("simple error, admin next table"));
2475
3553
        continue;
2476
3554
      case -1:           // error, message could be written to net
2477
3555
        /* purecov: begin inspected */
 
3556
        DBUG_PRINT("admin", ("severe error, stop"));
2478
3557
        goto err;
2479
3558
        /* purecov: end */
2480
3559
      default:           // should be 0 otherwise
 
3560
        DBUG_PRINT("admin", ("prepare_func succeeded"));
2481
3561
        ;
2482
3562
      }
2483
3563
    }
2484
3564
 
2485
3565
    /*
2486
 
      CHECK Table command is only command where VIEW allowed here and this
 
3566
      CHECK TABLE command is only command where VIEW allowed here and this
2487
3567
      command use only temporary teble method for VIEWs resolving => there
2488
3568
      can't be VIEW tree substitition of join view => if opening table
2489
 
      succeed then table->table will have real Table pointer as value (in
 
3569
      succeed then table->table will have real TABLE pointer as value (in
2490
3570
      case of join view substitution table->table can be 0, but here it is
2491
3571
      impossible)
2492
3572
    */
2493
3573
    if (!table->table)
2494
3574
    {
 
3575
      DBUG_PRINT("admin", ("open table failed"));
2495
3576
      if (!thd->warn_list.elements)
2496
 
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
3577
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
2497
3578
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2498
3579
      goto send_result;
2499
3580
    }
2501
3582
    if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
2502
3583
    {
2503
3584
      /* purecov: begin inspected */
2504
 
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
2505
 
      uint32_t length;
 
3585
      char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
 
3586
      uint length;
 
3587
      DBUG_PRINT("admin", ("sending error message"));
2506
3588
      protocol->prepare_for_resend();
2507
3589
      protocol->store(table_name, system_charset_info);
2508
3590
      protocol->store(operator_name, system_charset_info);
2509
3591
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2510
 
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2511
 
                       table_name);
 
3592
      length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
 
3593
                          table_name);
2512
3594
      protocol->store(buff, length, system_charset_info);
2513
3595
      ha_autocommit_or_rollback(thd, 0);
2514
3596
      end_trans(thd, COMMIT);
2524
3606
    /* Close all instances of the table to allow repair to rename files */
2525
3607
    if (lock_type == TL_WRITE && table->table->s->version)
2526
3608
    {
 
3609
      DBUG_PRINT("admin", ("removing table from cache"));
2527
3610
      pthread_mutex_lock(&LOCK_open);
2528
3611
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
2529
3612
                                              "Waiting to get writelock");
2533
3616
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2534
3617
                              RTFC_CHECK_KILLED_FLAG);
2535
3618
      thd->exit_cond(old_message);
 
3619
      DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
2536
3620
      if (thd->killed)
2537
3621
        goto err;
2538
3622
      open_for_modify= 0;
2541
3625
    if (table->table->s->crashed && operator_func == &handler::ha_check)
2542
3626
    {
2543
3627
      /* purecov: begin inspected */
 
3628
      DBUG_PRINT("admin", ("sending crashed warning"));
2544
3629
      protocol->prepare_for_resend();
2545
3630
      protocol->store(table_name, system_charset_info);
2546
3631
      protocol->store(operator_name, system_charset_info);
2559
3644
          (table->table->file->ha_check_for_upgrade(check_opt) ==
2560
3645
           HA_ADMIN_NEEDS_ALTER))
2561
3646
      {
 
3647
        DBUG_PRINT("admin", ("recreating table"));
2562
3648
        ha_autocommit_or_rollback(thd, 1);
2563
3649
        close_thread_tables(thd);
2564
3650
        tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2576
3662
      }
2577
3663
    }
2578
3664
 
 
3665
    DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
2579
3666
    result_code = (table->table->file->*operator_func)(thd, check_opt);
 
3667
    DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
2580
3668
 
2581
3669
send_result:
2582
3670
 
2583
3671
    lex->cleanup_after_one_table_open();
2584
3672
    thd->clear_error();  // these errors shouldn't get client
2585
3673
    {
2586
 
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
2587
 
      DRIZZLE_ERROR *err;
 
3674
      List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
 
3675
      MYSQL_ERROR *err;
2588
3676
      while ((err= it++))
2589
3677
      {
2590
3678
        protocol->prepare_for_resend();
2597
3685
        if (protocol->write())
2598
3686
          goto err;
2599
3687
      }
2600
 
      drizzle_reset_errors(thd, true);
 
3688
      mysql_reset_errors(thd, true);
2601
3689
    }
2602
3690
    protocol->prepare_for_resend();
2603
3691
    protocol->store(table_name, system_charset_info);
2605
3693
 
2606
3694
send_result_message:
2607
3695
 
 
3696
    DBUG_PRINT("info", ("result_code: %d", result_code));
2608
3697
    switch (result_code) {
2609
3698
    case HA_ADMIN_NOT_IMPLEMENTED:
2610
3699
      {
2611
3700
        char buf[ERRMSGSIZE+20];
2612
 
        uint32_t length=snprintf(buf, ERRMSGSIZE,
2613
 
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
 
3701
        uint length=my_snprintf(buf, ERRMSGSIZE,
 
3702
                                ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
2614
3703
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2615
3704
        protocol->store(buf, length, system_charset_info);
2616
3705
      }
2619
3708
    case HA_ADMIN_NOT_BASE_TABLE:
2620
3709
      {
2621
3710
        char buf[ERRMSGSIZE+20];
2622
 
        uint32_t length= snprintf(buf, ERRMSGSIZE,
2623
 
                              ER(ER_BAD_TABLE_ERROR), table_name);
 
3711
        uint length= my_snprintf(buf, ERRMSGSIZE,
 
3712
                                 ER(ER_BAD_TABLE_ERROR), table_name);
2624
3713
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2625
3714
        protocol->store(buf, length, system_charset_info);
2626
3715
      }
2666
3755
    {
2667
3756
      /*
2668
3757
        This is currently used only by InnoDB. ha_innobase::optimize() answers
2669
 
        "try with alter", so here we close the table, do an ALTER Table,
 
3758
        "try with alter", so here we close the table, do an ALTER TABLE,
2670
3759
        reopen the table and do ha_innobase::analyze() on it.
2671
3760
      */
2672
3761
      ha_autocommit_or_rollback(thd, 0);
2673
3762
      close_thread_tables(thd);
2674
 
      TableList *save_next_local= table->next_local,
 
3763
      TABLE_LIST *save_next_local= table->next_local,
2675
3764
                 *save_next_global= table->next_global;
2676
3765
      table->next_local= table->next_global= 0;
2677
3766
      tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2695
3784
      }
2696
3785
      if (result_code) // either mysql_recreate_table or analyze failed
2697
3786
      {
2698
 
        assert(thd->is_error());
 
3787
        DBUG_ASSERT(thd->is_error());
2699
3788
        if (thd->is_error())
2700
3789
        {
2701
3790
          const char *err_msg= thd->main_da.message();
2734
3823
    case HA_ADMIN_NEEDS_ALTER:
2735
3824
    {
2736
3825
      char buf[ERRMSGSIZE];
2737
 
      uint32_t length;
 
3826
      uint length;
2738
3827
 
2739
3828
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2740
 
      length=snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
 
3829
      length=my_snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
2741
3830
      protocol->store(buf, length, system_charset_info);
2742
3831
      fatal_error=1;
2743
3832
      break;
2746
3835
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
2747
3836
      {
2748
3837
        char buf[ERRMSGSIZE+20];
2749
 
        uint32_t length=snprintf(buf, ERRMSGSIZE,
2750
 
                             _("Unknown - internal error %d during operation"),
2751
 
                             result_code);
 
3838
        uint length=my_snprintf(buf, ERRMSGSIZE,
 
3839
                                "Unknown - internal error %d during operation",
 
3840
                                result_code);
2752
3841
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2753
3842
        protocol->store(buf, length, system_charset_info);
2754
3843
        fatal_error=1;
2781
3870
  }
2782
3871
 
2783
3872
  my_eof(thd);
2784
 
  return(false);
 
3873
  DBUG_RETURN(false);
2785
3874
 
2786
3875
err:
2787
3876
  ha_autocommit_or_rollback(thd, 1);
2789
3878
  close_thread_tables(thd);                     // Shouldn't be needed
2790
3879
  if (table)
2791
3880
    table->table=0;
2792
 
  return(true);
 
3881
  DBUG_RETURN(true);
2793
3882
}
2794
3883
 
2795
3884
 
2796
 
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3885
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
2797
3886
{
2798
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3887
  DBUG_ENTER("mysql_repair_table");
 
3888
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
2799
3889
                                "repair", TL_WRITE, 1,
2800
3890
                                test(check_opt->sql_flags & TT_USEFRM),
2801
3891
                                HA_OPEN_FOR_REPAIR,
2804
3894
}
2805
3895
 
2806
3896
 
2807
 
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3897
bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
2808
3898
{
2809
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3899
  DBUG_ENTER("mysql_optimize_table");
 
3900
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
2810
3901
                                "optimize", TL_WRITE, 1,0,0,0,
2811
3902
                                &handler::ha_optimize));
2812
3903
}
2825
3916
   true  error
2826
3917
*/
2827
3918
 
2828
 
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
 
3919
bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
2829
3920
                             LEX_STRING *key_cache_name)
2830
3921
{
2831
3922
  HA_CHECK_OPT check_opt;
2832
3923
  KEY_CACHE *key_cache;
 
3924
  DBUG_ENTER("mysql_assign_to_keycache");
2833
3925
 
2834
3926
  check_opt.init();
2835
3927
  pthread_mutex_lock(&LOCK_global_system_variables);
2837
3929
  {
2838
3930
    pthread_mutex_unlock(&LOCK_global_system_variables);
2839
3931
    my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
2840
 
    return(true);
 
3932
    DBUG_RETURN(true);
2841
3933
  }
2842
3934
  pthread_mutex_unlock(&LOCK_global_system_variables);
2843
3935
  check_opt.key_cache= key_cache;
2844
 
  return(mysql_admin_table(thd, tables, &check_opt,
 
3936
  DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
2845
3937
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
2846
3938
                                0, 0, &handler::assign_to_keycache));
2847
3939
}
2872
3964
    0     ok
2873
3965
*/
2874
3966
 
2875
 
int reassign_keycache_tables(THD *thd __attribute__((unused)),
2876
 
                             KEY_CACHE *src_cache,
2877
 
                             KEY_CACHE *dst_cache)
 
3967
int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
 
3968
                             KEY_CACHE *dst_cache)
2878
3969
{
2879
 
  assert(src_cache != dst_cache);
2880
 
  assert(src_cache->in_init);
 
3970
  DBUG_ENTER("reassign_keycache_tables");
 
3971
 
 
3972
  DBUG_ASSERT(src_cache != dst_cache);
 
3973
  DBUG_ASSERT(src_cache->in_init);
2881
3974
  src_cache->param_buff_size= 0;                // Free key cache
2882
3975
  ha_resize_key_cache(src_cache);
2883
3976
  ha_change_key_cache(src_cache, dst_cache);
2884
 
  return(0);
 
3977
  DBUG_RETURN(0);
2885
3978
}
2886
3979
 
 
3980
 
 
3981
 
2887
3982
/**
2888
3983
  @brief          Create frm file based on I_S table
2889
3984
 
2896
3991
    @retval       0                        success
2897
3992
    @retval       1                        error
2898
3993
*/
2899
 
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
 
3994
 
 
3995
 
 
3996
bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
2900
3997
                                  char *dst_path, HA_CREATE_INFO *create_info)
2901
3998
{
2902
3999
  HA_CREATE_INFO local_create_info;
2903
4000
  Alter_info alter_info;
2904
4001
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
2905
 
  uint32_t keys= schema_table->table->s->keys;
2906
 
  uint32_t db_options= 0;
 
4002
  uint keys= schema_table->table->s->keys;
 
4003
  uint db_options= 0;
 
4004
  DBUG_ENTER("mysql_create_like_schema_frm");
2907
4005
 
2908
 
  memset(&local_create_info, 0, sizeof(local_create_info));
 
4006
  bzero((char*) &local_create_info, sizeof(local_create_info));
2909
4007
  local_create_info.db_type= schema_table->table->s->db_type();
2910
4008
  local_create_info.row_type= schema_table->table->s->row_type;
2911
4009
  local_create_info.default_table_charset=default_charset_info;
2913
4011
  schema_table->table->use_all_columns();
2914
4012
  if (mysql_prepare_alter_table(thd, schema_table->table,
2915
4013
                                &local_create_info, &alter_info))
2916
 
    return(1);
 
4014
    DBUG_RETURN(1);
2917
4015
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
2918
4016
                                 tmp_table, &db_options,
2919
4017
                                 schema_table->table->file,
2920
4018
                                 &schema_table->table->s->key_info, &keys, 0))
2921
 
    return(1);
 
4019
    DBUG_RETURN(1);
2922
4020
  local_create_info.max_rows= 0;
2923
 
  if (mysql_create_frm(thd, dst_path, NULL, NULL,
 
4021
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
2924
4022
                       &local_create_info, alter_info.create_list,
2925
4023
                       keys, schema_table->table->s->key_info,
2926
4024
                       schema_table->table->file))
2927
 
    return(1);
2928
 
  return(0);
 
4025
    DBUG_RETURN(1);
 
4026
  DBUG_RETURN(0);
2929
4027
}
2930
4028
 
2931
4029
 
2944
4042
    true  error
2945
4043
*/
2946
4044
 
2947
 
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
 
4045
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
2948
4046
                             HA_CREATE_INFO *create_info)
2949
4047
{
2950
 
  Table *name_lock= 0;
 
4048
  TABLE *name_lock= 0;
2951
4049
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
2952
 
  uint32_t dst_path_length;
 
4050
  uint dst_path_length;
2953
4051
  char *db= table->db;
2954
4052
  char *table_name= table->table_name;
2955
4053
  int  err;
2956
4054
  bool res= true;
2957
 
  uint32_t not_used;
 
4055
  uint not_used;
 
4056
  DBUG_ENTER("mysql_create_like_table");
 
4057
 
 
4058
 
 
4059
  /* CREATE TABLE ... LIKE is not allowed for views. */
 
4060
  src_table->required_type= FRMTYPE_TABLE;
2958
4061
 
2959
4062
  /*
2960
4063
    By opening source table we guarantee that it exists and no concurrent
2966
4069
    operations which matter.
2967
4070
  */
2968
4071
  if (open_tables(thd, &src_table, &not_used, 0))
2969
 
    return(true);
2970
 
 
2971
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
 
4072
    DBUG_RETURN(true);
 
4073
 
 
4074
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
 
4075
 
 
4076
  DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
2972
4077
 
2973
4078
  /* 
2974
4079
    Check that destination tables does not exist. Note that its name
2993
4098
      goto table_exists;
2994
4099
  }
2995
4100
 
 
4101
  DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
 
4102
 
2996
4103
  /*
2997
4104
    Create a new table by copying from source table
2998
4105
 
3006
4113
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
3007
4114
    during the call to ha_create_table(). See bug #28614 for more info.
3008
4115
  */
3009
 
  pthread_mutex_lock(&LOCK_open);
 
4116
  VOID(pthread_mutex_lock(&LOCK_open));
3010
4117
  if (src_table->schema_table)
3011
4118
  {
3012
4119
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
3013
4120
    {
3014
 
      pthread_mutex_unlock(&LOCK_open);
 
4121
      VOID(pthread_mutex_unlock(&LOCK_open));
3015
4122
      goto err;
3016
4123
    }
3017
4124
  }
3021
4128
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
3022
4129
    else
3023
4130
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
3024
 
    pthread_mutex_unlock(&LOCK_open);
 
4131
    VOID(pthread_mutex_unlock(&LOCK_open));
3025
4132
    goto err;
3026
4133
  }
3027
4134
 
3030
4137
    creation, instead create the table directly (for both normal
3031
4138
    and temporary tables).
3032
4139
  */
 
4140
  DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
 
4141
 
3033
4142
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
3034
4143
  if (thd->variables.keep_files_on_create)
3035
4144
    create_info->options|= HA_CREATE_KEEP_FILES;
3036
4145
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
3037
 
  pthread_mutex_unlock(&LOCK_open);
 
4146
  VOID(pthread_mutex_unlock(&LOCK_open));
3038
4147
 
3039
4148
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3040
4149
  {
3053
4162
    goto err;       /* purecov: inspected */
3054
4163
  }
3055
4164
 
 
4165
  DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
 
4166
 
3056
4167
  /*
3057
4168
    We have to write the query before we unlock the tables.
3058
4169
  */
3089
4200
          of this function.
3090
4201
        */
3091
4202
        table->table= name_lock;
3092
 
        pthread_mutex_lock(&LOCK_open);
 
4203
        VOID(pthread_mutex_lock(&LOCK_open));
3093
4204
        if (reopen_name_locked_table(thd, table, false))
3094
4205
        {
3095
 
          pthread_mutex_unlock(&LOCK_open);
 
4206
          VOID(pthread_mutex_unlock(&LOCK_open));
3096
4207
          goto err;
3097
4208
        }
3098
 
        pthread_mutex_unlock(&LOCK_open);
 
4209
        VOID(pthread_mutex_unlock(&LOCK_open));
3099
4210
 
3100
 
        int result= store_create_info(thd, table, &query,
 
4211
        IF_DBUG(int result=) store_create_info(thd, table, &query,
3101
4212
                                               create_info);
3102
4213
 
3103
 
        assert(result == 0); // store_create_info() always return 0
 
4214
        DBUG_ASSERT(result == 0); // store_create_info() always return 0
3104
4215
        write_bin_log(thd, true, query.ptr(), query.length());
3105
4216
      }
3106
4217
      else                                      // Case 1
3119
4230
table_exists:
3120
4231
  if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
3121
4232
  {
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,
 
4233
    char warn_buff[MYSQL_ERRMSG_SIZE];
 
4234
    my_snprintf(warn_buff, sizeof(warn_buff),
 
4235
                ER(ER_TABLE_EXISTS_ERROR), table_name);
 
4236
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3126
4237
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3127
4238
    res= false;
3128
4239
  }
3136
4247
    unlink_open_table(thd, name_lock, false);
3137
4248
    pthread_mutex_unlock(&LOCK_open);
3138
4249
  }
3139
 
  return(res);
 
4250
  DBUG_RETURN(res);
3140
4251
}
3141
4252
 
3142
4253
 
3143
 
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
4254
bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
3144
4255
{
3145
4256
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3146
4257
 
3147
 
  return(mysql_admin_table(thd, tables, check_opt,
 
4258
  DBUG_ENTER("mysql_analyze_table");
 
4259
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
3148
4260
                                "analyze", lock_type, 1, 0, 0, 0,
3149
4261
                                &handler::ha_analyze));
3150
4262
}
3151
4263
 
3152
4264
 
3153
 
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
 
4265
bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
3154
4266
{
3155
4267
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3156
4268
 
3157
 
  return(mysql_admin_table(thd, tables, check_opt,
 
4269
  DBUG_ENTER("mysql_check_table");
 
4270
  DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
3158
4271
                                "check", lock_type,
3159
4272
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
3160
4273
                                &handler::ha_check));
3164
4277
/* table_list should contain just one table */
3165
4278
static int
3166
4279
mysql_discard_or_import_tablespace(THD *thd,
3167
 
                                   TableList *table_list,
 
4280
                                   TABLE_LIST *table_list,
3168
4281
                                   enum tablespace_op_type tablespace_op)
3169
4282
{
3170
 
  Table *table;
3171
 
  bool discard;
 
4283
  TABLE *table;
 
4284
  my_bool discard;
3172
4285
  int error;
 
4286
  DBUG_ENTER("mysql_discard_or_import_tablespace");
3173
4287
 
3174
4288
  /*
3175
4289
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
3176
 
    ALTER Table
 
4290
    ALTER TABLE
3177
4291
  */
3178
4292
 
3179
 
  thd->set_proc_info("discard_or_import_tablespace");
 
4293
  thd_proc_info(thd, "discard_or_import_tablespace");
3180
4294
 
3181
4295
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3182
4296
 
3188
4302
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
3189
4303
  {
3190
4304
    thd->tablespace_op=false;
3191
 
    return(-1);
 
4305
    DBUG_RETURN(-1);
3192
4306
  }
3193
4307
 
3194
4308
  error= table->file->ha_discard_or_import_tablespace(discard);
3195
4309
 
3196
 
  thd->set_proc_info("end");
 
4310
  thd_proc_info(thd, "end");
3197
4311
 
3198
4312
  if (error)
3199
4313
    goto err;
3200
4314
 
3201
 
  /* The ALTER Table is always in its own transaction */
 
4315
  /* The ALTER TABLE is always in its own transaction */
3202
4316
  error = ha_autocommit_or_rollback(thd, 0);
3203
4317
  if (end_active_trans(thd))
3204
4318
    error=1;
3213
4327
  if (error == 0)
3214
4328
  {
3215
4329
    my_ok(thd);
3216
 
    return(0);
 
4330
    DBUG_RETURN(0);
3217
4331
  }
3218
4332
 
3219
4333
  table->file->print_error(error, MYF(0));
3220
4334
    
3221
 
  return(-1);
 
4335
  DBUG_RETURN(-1);
3222
4336
}
3223
4337
 
3224
4338
/**
3227
4341
 
3228
4342
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
3229
4343
{
3230
 
  uint32_t flags= alter_info->flags;
 
4344
  uint flags= alter_info->flags;
3231
4345
 
3232
4346
  if (ALTER_ADD_COLUMN & flags)
3233
4347
    *alter_flags|= HA_ADD_COLUMN;
3272
4386
   table has in arguments create_list, key_list and create_info.
3273
4387
 
3274
4388
   By comparing the changes between the original and new table
3275
 
   we can determine how much it has changed after ALTER Table
 
4389
   we can determine how much it has changed after ALTER TABLE
3276
4390
   and whether we need to make a copy of the table, or just change
3277
4391
   the .frm file.
3278
4392
 
3290
4404
static
3291
4405
bool
3292
4406
compare_tables(THD *thd,
3293
 
               Table *table,
 
4407
               TABLE *table,
3294
4408
               Alter_info *alter_info,
3295
4409
                           HA_CREATE_INFO *create_info,
3296
 
               uint32_t order_num,
 
4410
               uint order_num,
3297
4411
               HA_ALTER_FLAGS *alter_flags,
3298
4412
               HA_ALTER_INFO *ha_alter_info,
3299
 
               uint32_t *table_changes)
 
4413
               uint *table_changes)
3300
4414
{
3301
4415
  Field **f_ptr, *field;
3302
 
  uint32_t table_changes_local= 0;
 
4416
  uint table_changes_local= 0;
3303
4417
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
3304
4418
  Create_field *new_field;
3305
4419
  KEY_PART_INFO *key_part;
3309
4423
    create_info->varchar will be reset in mysql_prepare_create_table.
3310
4424
  */
3311
4425
  bool varchar= create_info->varchar;
 
4426
  DBUG_ENTER("compare_tables");
3312
4427
 
3313
4428
  {
3314
4429
    /*
3323
4438
      like to keep compare_tables() idempotent (not altering any
3324
4439
      of the arguments) we create a copy of alter_info here and
3325
4440
      pass it to mysql_prepare_create_table, then use the result
3326
 
      to evaluate possibility of fast ALTER Table, and then
 
4441
      to evaluate possibility of fast ALTER TABLE, and then
3327
4442
      destroy the copy.
3328
4443
    */
3329
4444
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
3330
4445
    THD *thd= table->in_use;
3331
 
    uint32_t db_options= 0; /* not used */
 
4446
    uint db_options= 0; /* not used */
3332
4447
    /* Create the prepared information. */
3333
4448
    if (mysql_prepare_create_table(thd, create_info,
3334
4449
                                   &tmp_alter_info,
3338
4453
                                   &ha_alter_info->key_info_buffer,
3339
4454
                                   &ha_alter_info->key_count,
3340
4455
                                   /* select_field_count */ 0))
3341
 
      return(true);
 
4456
      DBUG_RETURN(true);
3342
4457
    /* Allocate result buffers. */
3343
4458
    if (! (ha_alter_info->index_drop_buffer=
3344
4459
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
3345
4460
        ! (ha_alter_info->index_add_buffer=
3346
4461
           (uint*) thd->alloc(sizeof(uint) *
3347
4462
                              tmp_alter_info.key_list.elements)))
3348
 
      return(true);
 
4463
      DBUG_RETURN(true);
3349
4464
  }
3350
4465
  /*
3351
4466
    First we setup ha_alter_flags based on what was detected
3353
4468
  */
3354
4469
  setup_ha_alter_flags(alter_info, alter_flags);
3355
4470
 
 
4471
#ifndef DBUG_OFF
 
4472
  {
 
4473
    char dbug_string[HA_MAX_ALTER_FLAGS+1];
 
4474
    alter_flags->print(dbug_string);
 
4475
    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
 
4476
  }
 
4477
#endif
3356
4478
 
3357
4479
  /*
3358
4480
    Some very basic checks. If number of fields changes, or the
3359
 
    handler, we need to run full ALTER Table. In the future
 
4481
    handler, we need to run full ALTER TABLE. In the future
3360
4482
    new fields can be added and old dropped without copy, but
3361
4483
    not yet.
3362
4484
 
3363
 
    Test also that engine was not given during ALTER Table, or
 
4485
    Test also that engine was not given during ALTER TABLE, or
3364
4486
    we are force to run regular alter table (copy).
3365
 
    E.g. ALTER Table tbl_name ENGINE=MyISAM.
 
4487
    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
3366
4488
 
3367
4489
    For the following ones we also want to run regular alter table:
3368
 
    ALTER Table tbl_name order_st BY ..
3369
 
    ALTER Table tbl_name CONVERT TO CHARACTER SET ..
 
4490
    ALTER TABLE tbl_name ORDER BY ..
 
4491
    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
3370
4492
 
3371
4493
    At the moment we can't handle altering temporary tables without a copy.
3372
 
    We also test if OPTIMIZE Table was given and was mapped to alter table.
 
4494
    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
3373
4495
    In that case we always do full copy.
3374
4496
 
3375
4497
    There was a bug prior to mysql-4.0.25. Number of null fields was
3431
4553
    /* Don't pack rows in old tables if the user has requested this. */
3432
4554
    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
3433
4555
        (new_field->flags & BLOB_FLAG) ||
3434
 
        (new_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
4556
        (new_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
3435
4557
      create_info->table_options|= HA_OPTION_PACK_RECORD;
3436
4558
 
3437
4559
    /* Check how fields have been modified */
3441
4563
      if (!(table_changes_local= field->is_equal(new_field)))
3442
4564
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3443
4565
 
3444
 
      /*
3445
 
        Check if the altered column is a stored virtual field.
3446
 
        TODO: Mark such a column with an alter flag only if
3447
 
        the expression functions are not equal. 
3448
 
      */
3449
 
      if (field->is_stored && field->vcol_info)
3450
 
        *alter_flags|= HA_ALTER_STORED_VCOL;
3451
 
 
3452
4566
      /* Check if field was renamed */
3453
4567
      field->flags&= ~FIELD_IS_RENAMED;
3454
4568
      if (my_strcasecmp(system_charset_info,
3486
4600
  KEY *new_key_end=
3487
4601
       ha_alter_info->key_info_buffer + ha_alter_info->key_count;
3488
4602
 
 
4603
  DBUG_PRINT("info", ("index count old: %d  new: %d",
 
4604
                      table->s->keys, ha_alter_info->key_count));
3489
4605
  /*
3490
4606
    Step through all keys of the old table and search matching new keys.
3491
4607
  */
3523
4639
      else
3524
4640
        *alter_flags|= HA_DROP_INDEX;
3525
4641
      *table_changes= IS_EQUAL_NO;
 
4642
      DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
3526
4643
      continue;
3527
4644
    }
3528
4645
 
3595
4712
        field->flags|= FIELD_IN_ADD_INDEX;
3596
4713
    }
3597
4714
    *table_changes= IS_EQUAL_NO;
 
4715
    DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
3598
4716
  }
3599
4717
  /*end of for (; table_key < table_key_end;) */
3600
4718
 
3637
4755
      else
3638
4756
        *alter_flags|= HA_ADD_INDEX;
3639
4757
      *table_changes= IS_EQUAL_NO;
 
4758
      DBUG_PRINT("info", ("index added: '%s'", new_key->name));
3640
4759
    }
3641
4760
  }
 
4761
#ifndef DBUG_OFF
 
4762
  {
 
4763
    char dbug_string[HA_MAX_ALTER_FLAGS+1];
 
4764
    alter_flags->print(dbug_string);
 
4765
    DBUG_PRINT("info", ("alter_flags:  %s", (char *) dbug_string));
 
4766
  }
 
4767
#endif
3642
4768
 
3643
 
  return(false);
 
4769
  DBUG_RETURN(false);
3644
4770
}
3645
4771
 
3646
4772
 
3647
4773
/*
3648
 
  Manages enabling/disabling of indexes for ALTER Table
 
4774
  Manages enabling/disabling of indexes for ALTER TABLE
3649
4775
 
3650
4776
  SYNOPSIS
3651
4777
    alter_table_manage_keys()
3660
4786
*/
3661
4787
 
3662
4788
static
3663
 
bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
 
4789
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
3664
4790
                             enum enum_enable_or_disable keys_onoff)
3665
4791
{
3666
4792
  int error= 0;
 
4793
  DBUG_ENTER("alter_table_manage_keys");
 
4794
  DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
 
4795
             table, indexes_were_disabled, keys_onoff));
 
4796
 
3667
4797
  switch (keys_onoff) {
3668
4798
  case ENABLE:
3669
4799
    error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
3678
4808
 
3679
4809
  if (error == HA_ERR_WRONG_COMMAND)
3680
4810
  {
3681
 
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4811
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3682
4812
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3683
4813
                        table->s->table_name.str);
3684
4814
    error= 0;
3685
4815
  } else if (error)
3686
4816
    table->file->print_error(error, MYF(0));
3687
4817
 
3688
 
  return(error);
 
4818
  DBUG_RETURN(error);
3689
4819
}
3690
4820
 
3691
4821
int create_temporary_table(THD *thd,
3692
 
                           Table *table,
 
4822
                           TABLE *table,
3693
4823
                           char *new_db,
3694
4824
                           char *tmp_name,
3695
4825
                           HA_CREATE_INFO *create_info,
3699
4829
  int error;
3700
4830
  char index_file[FN_REFLEN], data_file[FN_REFLEN];
3701
4831
  handlerton *old_db_type, *new_db_type;
 
4832
  DBUG_ENTER("create_temporary_table");
3702
4833
  old_db_type= table->s->db_type();
3703
4834
  new_db_type= create_info->db_type;
3704
4835
  /*
3730
4861
    if (create_info->index_file_name)
3731
4862
    {
3732
4863
      /* Fix index_file_name to have 'tmp_name' as basename */
3733
 
      my_stpcpy(index_file, tmp_name);
 
4864
      strmov(index_file, tmp_name);
3734
4865
      create_info->index_file_name=fn_same(index_file,
3735
4866
                                           create_info->index_file_name,
3736
4867
                                           1);
3738
4869
    if (create_info->data_file_name)
3739
4870
    {
3740
4871
      /* Fix data_file_name to have 'tmp_name' as basename */
3741
 
      my_stpcpy(data_file, tmp_name);
 
4872
      strmov(data_file, tmp_name);
3742
4873
      create_info->data_file_name=fn_same(data_file,
3743
4874
                                          create_info->data_file_name,
3744
4875
                                          1);
3747
4878
  else
3748
4879
    create_info->data_file_name=create_info->index_file_name=0;
3749
4880
 
 
4881
  if (new_db_type == old_db_type)
 
4882
  {
 
4883
    /*
 
4884
       Table has not changed storage engine.
 
4885
       If STORAGE and TABLESPACE have not been changed than copy them
 
4886
       from the original table
 
4887
    */
 
4888
    if (!create_info->tablespace &&
 
4889
        table->s->tablespace &&
 
4890
        create_info->default_storage_media == HA_SM_DEFAULT)
 
4891
      create_info->tablespace= table->s->tablespace;
 
4892
    if (create_info->default_storage_media == HA_SM_DEFAULT)
 
4893
      create_info->default_storage_media= table->s->default_storage_media;
 
4894
   }
 
4895
 
3750
4896
  /*
3751
4897
    Create a table with a temporary name.
3752
4898
    With create_info->frm_only == 1 this creates a .frm file only.
3757
4903
                            create_info, alter_info, 1, 0);
3758
4904
  reenable_binlog(thd);
3759
4905
 
3760
 
  return(error);
 
4906
  DBUG_RETURN(error);
3761
4907
}
3762
4908
 
3763
4909
/*
3780
4926
    The temporary table is created without storing it in any storage engine
3781
4927
    and is opened only to get the table struct and frm file reference.
3782
4928
*/
3783
 
Table *create_altered_table(THD *thd,
3784
 
                            Table *table,
 
4929
TABLE *create_altered_table(THD *thd,
 
4930
                            TABLE *table,
3785
4931
                            char *new_db,
3786
4932
                            HA_CREATE_INFO *create_info,
3787
4933
                            Alter_info *alter_info,
3789
4935
{
3790
4936
  int error;
3791
4937
  HA_CREATE_INFO altered_create_info(*create_info);
3792
 
  Table *altered_table;
 
4938
  TABLE *altered_table;
3793
4939
  char tmp_name[80];
3794
4940
  char path[FN_REFLEN];
 
4941
  DBUG_ENTER("create_altered_table");
3795
4942
 
3796
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3797
 
           tmp_file_prefix, current_pid, thd->thread_id);
 
4943
  my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
 
4944
              tmp_file_prefix, current_pid, thd->thread_id);
3798
4945
  /* Safety fix for InnoDB */
3799
4946
  if (lower_case_table_names)
3800
4947
    my_casedn_str(files_charset_info, tmp_name);
3804
4951
                                     &altered_create_info,
3805
4952
                                     alter_info, db_change)))
3806
4953
  {
3807
 
    return(NULL);
 
4954
    DBUG_PRINT("info", ("Error %u while creating temporary table", error));
 
4955
    DBUG_RETURN(NULL);
3808
4956
  };
3809
4957
 
3810
4958
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
3811
4959
                       FN_IS_TMP);
3812
4960
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
3813
4961
                                      OTM_ALTER);
3814
 
  return(altered_table);
 
4962
  DBUG_RETURN(altered_table);
3815
4963
 
3816
 
  return(NULL);
 
4964
  DBUG_RETURN(NULL);
3817
4965
}
3818
4966
 
3819
4967
 
3843
4991
    the table.
3844
4992
*/
3845
4993
int mysql_fast_or_online_alter_table(THD *thd,
3846
 
                                     Table *table,
3847
 
                                     Table *altered_table,
 
4994
                                     TABLE *table,
 
4995
                                     TABLE *altered_table,
3848
4996
                                     HA_CREATE_INFO *create_info,
3849
4997
                                     HA_ALTER_INFO *alter_info,
3850
4998
                                     HA_ALTER_FLAGS *ha_alter_flags,
3852
5000
{
3853
5001
  int error= 0;
3854
5002
  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER)?true:false;
3855
 
  Table *t_table;
 
5003
  TABLE *t_table;
3856
5004
 
 
5005
  DBUG_ENTER(" mysql_fast_or_online_alter_table");
3857
5006
  if (online)
3858
5007
  {
3859
5008
   /*
3887
5036
    The final .frm file is already created as a temporary file
3888
5037
    and will be renamed to the original table name.
3889
5038
  */
3890
 
  pthread_mutex_lock(&LOCK_open);
 
5039
  VOID(pthread_mutex_lock(&LOCK_open));
3891
5040
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3892
5041
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3893
5042
                          keys_onoff);
3901
5050
                         table->s->table_name.str, FN_FROM_IS_TMP))
3902
5051
  {
3903
5052
    error= 1;
3904
 
    pthread_mutex_unlock(&LOCK_open);
 
5053
    VOID(pthread_mutex_unlock(&LOCK_open));
3905
5054
    goto err;
3906
5055
  }
3907
5056
  broadcast_refresh();
3908
 
  pthread_mutex_unlock(&LOCK_open);
 
5057
  VOID(pthread_mutex_unlock(&LOCK_open));
3909
5058
 
3910
5059
  /*
3911
 
    The ALTER Table is always in its own transaction.
 
5060
    The ALTER TABLE is always in its own transaction.
3912
5061
    Commit must not be called while LOCK_open is locked. It could call
3913
5062
    wait_if_global_read_lock(), which could create a deadlock if called
3914
5063
    with LOCK_open.
3921
5070
    goto err;
3922
5071
  if (online)
3923
5072
  {
3924
 
    pthread_mutex_lock(&LOCK_open);
 
5073
    VOID(pthread_mutex_lock(&LOCK_open));
3925
5074
    if (reopen_table(table))
3926
5075
    {
3927
5076
      error= -1;
3928
5077
      goto err;
3929
5078
    }
3930
 
    pthread_mutex_unlock(&LOCK_open);
 
5079
    VOID(pthread_mutex_unlock(&LOCK_open));
3931
5080
    t_table= table;
3932
5081
 
3933
5082
   /*
3941
5090
 
3942
5091
    /*
3943
5092
      We are going to reopen table down on the road, so we have to restore
3944
 
      state of the Table object which we used for obtaining of handler
 
5093
      state of the TABLE object which we used for obtaining of handler
3945
5094
      object to make it suitable for reopening.
3946
5095
    */
3947
 
    assert(t_table == table);
 
5096
    DBUG_ASSERT(t_table == table);
3948
5097
    table->open_placeholder= 1;
3949
 
    pthread_mutex_lock(&LOCK_open);
 
5098
    VOID(pthread_mutex_lock(&LOCK_open));
3950
5099
    close_handle_and_leave_table_as_lock(table);
3951
 
    pthread_mutex_unlock(&LOCK_open);
 
5100
    VOID(pthread_mutex_unlock(&LOCK_open));
3952
5101
  }
3953
5102
 
3954
5103
 err:
3955
5104
  if (error)
3956
 
    return(error);
3957
 
  return 0;
 
5105
    DBUG_PRINT("info", ("Got error %u", error));
 
5106
  DBUG_RETURN(error);
3958
5107
}
3959
5108
 
3960
5109
 
3961
5110
/**
3962
 
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
 
5111
  Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
3963
5112
 
3964
 
  This function transforms parse output of ALTER Table - lists of
 
5113
  This function transforms parse output of ALTER TABLE - lists of
3965
5114
  columns and keys to add, drop or modify into, essentially,
3966
5115
  CREATE TABLE definition - a list of columns and keys of the new
3967
5116
  table. While doing so, it also performs some (bug not all)
3968
5117
  semantic checks.
3969
5118
 
3970
5119
  This function is invoked when we know that we're going to
3971
 
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
 
5120
  perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
3972
5121
  is not possible, perhaps because the ALTER statement contains
3973
5122
  instructions that require change in table data, not only in
3974
5123
  table definition or indexes.
3979
5128
                              Used as an interface to the storage engine
3980
5129
                              to acquire additional information about
3981
5130
                              the original table.
3982
 
  @param[in,out]  create_info A blob with CREATE/ALTER Table
 
5131
  @param[in,out]  create_info A blob with CREATE/ALTER TABLE
3983
5132
                              parameters
3984
5133
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
3985
5134
                              Originally create_info was used only in
3986
 
                              CREATE TABLE and alter_info only in ALTER Table.
 
5135
                              CREATE TABLE and alter_info only in ALTER TABLE.
3987
5136
                              But since ALTER might end-up doing CREATE,
3988
5137
                              this distinction is gone and we just carry
3989
5138
                              around two structures.
3995
5144
    Prepares alter_info->create_list and alter_info->key_list with
3996
5145
    columns and keys of the new table.
3997
5146
  @retval true   error, out of memory or a semantical error in ALTER
3998
 
                 Table instructions
 
5147
                 TABLE instructions
3999
5148
  @retval false  success
4000
5149
*/
4001
5150
 
4002
5151
static bool
4003
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
5152
mysql_prepare_alter_table(THD *thd, TABLE *table,
4004
5153
                          HA_CREATE_INFO *create_info,
4005
5154
                          Alter_info *alter_info)
4006
5155
{
4015
5164
  List_iterator<Create_field> find_it(new_create_list);
4016
5165
  List_iterator<Create_field> field_it(new_create_list);
4017
5166
  List<Key_part_spec> key_parts;
4018
 
  uint32_t db_create_options= (table->s->db_create_options
 
5167
  uint db_create_options= (table->s->db_create_options
4019
5168
                           & ~(HA_OPTION_PACK_RECORD));
4020
 
  uint32_t used_fields= create_info->used_fields;
 
5169
  uint used_fields= create_info->used_fields;
4021
5170
  KEY *key_info=table->key_info;
4022
5171
  bool rc= true;
4023
5172
 
 
5173
  DBUG_ENTER("mysql_prepare_alter_table");
4024
5174
 
4025
5175
  create_info->varchar= false;
4026
5176
  /* Let new create options override the old ones */
4030
5180
    create_info->max_rows= table->s->max_rows;
4031
5181
  if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
4032
5182
    create_info->avg_row_length= table->s->avg_row_length;
4033
 
  if (!(used_fields & HA_CREATE_USED_BLOCK_SIZE))
4034
 
    create_info->block_size= table->s->block_size;
4035
5183
  if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
4036
5184
    create_info->default_table_charset= table->s->table_charset;
4037
5185
  if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
4042
5190
  }
4043
5191
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
4044
5192
    create_info->key_block_size= table->s->key_block_size;
 
5193
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
 
5194
    create_info->transactional= table->s->transactional;
4045
5195
 
4046
5196
  restore_record(table, s->default_values);     // Empty record for DEFAULT
4047
5197
  Create_field *def;
4052
5202
  Field **f_ptr,*field;
4053
5203
  for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
4054
5204
    {
 
5205
    if (field->type() == MYSQL_TYPE_STRING)
 
5206
      create_info->varchar= true;
4055
5207
    /* Check if field should be dropped */
4056
5208
    Alter_drop *drop;
4057
5209
    drop_it.rewind();
4086
5238
    if (def)
4087
5239
    {                                           // Field is changed
4088
5240
      def->field=field;
4089
 
      if (field->is_stored != def->is_stored)
4090
 
      {
4091
 
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
4092
 
                 MYF(0),
4093
 
                 "Changing the STORED status");
4094
 
        goto err;
4095
 
      }
4096
5241
      if (!def->after)
4097
5242
        {
4098
5243
        new_create_list.push_back(def);
4116
5261
        }
4117
5262
      if (alter)
4118
5263
        {
4119
 
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
 
5264
        if (def->sql_type == MYSQL_TYPE_BLOB)
4120
5265
        {
4121
5266
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
4122
5267
          goto err;
4142
5287
      either has a default value or the '0000-00-00' is allowed by the
4143
5288
      set sql mode.
4144
5289
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4145
 
      flag to allow ALTER Table only if the table to be altered is empty.
 
5290
      flag to allow ALTER TABLE only if the table to be altered is empty.
4146
5291
      */
4147
 
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
4148
 
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
 
5292
    if ((def->sql_type == MYSQL_TYPE_DATE ||
 
5293
         def->sql_type == MYSQL_TYPE_NEWDATE ||
 
5294
         def->sql_type == MYSQL_TYPE_DATETIME) &&
4149
5295
         !alter_info->datetime_field &&
4150
5296
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4151
5297
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
4174
5320
      find_it.after(def);                       // Put element after this
4175
5321
      /*
4176
5322
        XXX: hack for Bug#28427.
4177
 
        If column order has changed, force OFFLINE ALTER Table
 
5323
        If column order has changed, force OFFLINE ALTER TABLE
4178
5324
        without querying engine capabilities.  If we ever have an
4179
 
        engine that supports online ALTER Table CHANGE COLUMN
 
5325
        engine that supports online ALTER TABLE CHANGE COLUMN
4180
5326
        <name> AFTER <name1> (Falcon?), this fix will effectively
4181
5327
        disable the capability.
4182
5328
        TODO: detect the situation in compare_tables, behave based
4208
5354
    for which some fields exists.
4209
5355
    */
4210
5356
 
4211
 
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
 
5357
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
4212
5358
    {
4213
5359
    char *key_name= key_info->name;
4214
5360
    Alter_drop *drop;
4227
5373
 
4228
5374
    KEY_PART_INFO *key_part= key_info->key_part;
4229
5375
    key_parts.empty();
4230
 
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
 
5376
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
4231
5377
    {
4232
5378
      if (!key_part->field)
4233
5379
        continue;                               // Wrong field (from UNIREG)
4248
5394
      }
4249
5395
      if (!cfield)
4250
5396
        continue;                               // Field is removed
4251
 
      uint32_t key_part_length=key_part->length;
 
5397
      uint key_part_length=key_part->length;
4252
5398
      if (cfield->field)                        // Not new field
4253
5399
      {
4254
5400
        /*
4281
5427
      KEY_CREATE_INFO key_create_info;
4282
5428
      Key *key;
4283
5429
      enum Key::Keytype key_type;
4284
 
      memset(&key_create_info, 0, sizeof(key_create_info));
 
5430
      bzero((char*) &key_create_info, sizeof(key_create_info));
4285
5431
 
4286
5432
      key_create_info.algorithm= key_info->algorithm;
4287
5433
      if (key_info->flags & HA_USES_BLOCK_SIZE)
4310
5456
    Key *key;
4311
5457
    while ((key=key_it++))                      // Add new keys
4312
5458
    {
4313
 
      if (key->type == Key::FOREIGN_KEY &&
4314
 
          ((Foreign_key *)key)->validate(new_create_list))
4315
 
        goto err;
4316
5459
      if (key->type != Key::FOREIGN_KEY)
4317
5460
        new_key_list.push_back(key);
4318
5461
      if (key->name.str &&
4364
5507
  alter_info->create_list.swap(new_create_list);
4365
5508
  alter_info->key_list.swap(new_key_list);
4366
5509
err:
4367
 
  return(rc);
 
5510
  DBUG_RETURN(rc);
4368
5511
}
4369
5512
 
4370
5513
 
4381
5524
      table_list       The table to change.
4382
5525
      alter_info       Lists of fields, keys to be changed, added
4383
5526
                       or dropped.
4384
 
      order_num        How many order_st BY fields has been specified.
4385
 
      order            List of fields to order_st BY.
4386
 
      ignore           Whether we have ALTER IGNORE Table
 
5527
      order_num        How many ORDER BY fields has been specified.
 
5528
      order            List of fields to ORDER BY.
 
5529
      ignore           Whether we have ALTER IGNORE TABLE
4387
5530
 
4388
5531
  DESCRIPTION
4389
5532
    This is a veery long function and is everything but the kitchen sink :)
4390
 
    It is used to alter a table and not only by ALTER Table but also
 
5533
    It is used to alter a table and not only by ALTER TABLE but also
4391
5534
    CREATE|DROP INDEX are mapped on this function.
4392
5535
 
4393
 
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
 
5536
    When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
4394
5537
    or both, then this function short cuts its operation by renaming
4395
5538
    the table and/or enabling/disabling the keys. In this case, the FRM is
4396
5539
    not changed, directly by mysql_alter_table. However, if there is a
4412
5555
 
4413
5556
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
4414
5557
                       HA_CREATE_INFO *create_info,
4415
 
                       TableList *table_list,
 
5558
                       TABLE_LIST *table_list,
4416
5559
                       Alter_info *alter_info,
4417
 
                       uint32_t order_num, order_st *order, bool ignore)
 
5560
                       uint order_num, ORDER *order, bool ignore)
4418
5561
{
4419
 
  Table *table, *new_table=0, *name_lock= 0;;
 
5562
  TABLE *table, *new_table=0, *name_lock= 0;;
4420
5563
  int error= 0;
4421
5564
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4422
5565
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4424
5567
  ha_rows copied= 0,deleted= 0;
4425
5568
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4426
5569
  legacy_db_type table_type;
 
5570
  frm_type_enum frm_type;
 
5571
  DBUG_ENTER("mysql_alter_table");
4427
5572
 
4428
5573
  if (table_list && table_list->schema_table)
4429
5574
  {
4430
5575
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
4431
 
    return(true);
 
5576
    DBUG_RETURN(true);
4432
5577
  }
4433
5578
 
4434
5579
  /*
4436
5581
    to simplify further comparisons: we want to see if it's a RENAME
4437
5582
    later just by comparing the pointers, avoiding the need for strcmp.
4438
5583
  */
4439
 
  thd->set_proc_info("init");
 
5584
  thd_proc_info(thd, "init");
4440
5585
  table_name=table_list->table_name;
4441
5586
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4442
5587
  db=table_list->db;
4446
5591
 
4447
5592
  mysql_ha_rm_tables(thd, table_list, false);
4448
5593
 
4449
 
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
 
5594
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
4450
5595
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4451
5596
    /* Conditionally writes to binlog. */
4452
 
    return(mysql_discard_or_import_tablespace(thd,table_list,
4453
 
                                              alter_info->tablespace_op));
 
5597
    DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
 
5598
                                                   alter_info->tablespace_op));
4454
5599
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
4455
 
           "/", table_name, reg_ext, NULL);
 
5600
           "/", table_name, reg_ext, NullS);
4456
5601
  (void) unpack_filename(new_name_buff, new_name_buff);
4457
5602
  /*
4458
5603
    If this is just a rename of a view, short cut to the
4459
5604
    following scenario: 1) lock LOCK_open 2) do a RENAME
4460
5605
    2) unlock LOCK_open.
4461
5606
    This is a copy-paste added to make sure
4462
 
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
 
5607
    ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
4463
5608
    as an independent branch in mysql_execute_command. The need
4464
 
    for a copy-paste arose because the main code flow of ALTER Table
 
5609
    for a copy-paste arose because the main code flow of ALTER TABLE
4465
5610
    ... RENAME tries to use open_ltable, which does not work for views
4466
5611
    (open_ltable was never modified to merge table lists of child tables
4467
5612
    into the main table list, like open_tables does).
4468
5613
    This code is wrong and will be removed, please do not copy.
4469
5614
  */
4470
 
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
 
5615
  frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
4471
5616
 
4472
5617
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
4473
 
    return(true);
 
5618
    DBUG_RETURN(true);
4474
5619
  table->use_all_columns();
4475
5620
 
 
5621
  /*
 
5622
    Prohibit changing of the UNION list of a non-temporary MERGE table
 
5623
    under LOCK tables. It would be quite difficult to reuse a shrinked
 
5624
    set of tables from the old table or to open a new TABLE object for
 
5625
    an extended list and verify that they belong to locked tables.
 
5626
  */
 
5627
  if (thd->locked_tables &&
 
5628
      (create_info->used_fields & HA_CREATE_USED_UNION) &&
 
5629
      (table->s->tmp_table == NO_TMP_TABLE))
 
5630
  {
 
5631
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
5632
    DBUG_RETURN(true);
 
5633
  }
 
5634
 
4476
5635
  /* Check that we are not trying to rename to an existing table */
4477
5636
  if (new_name)
4478
5637
  {
4479
 
    my_stpcpy(new_name_buff,new_name);
4480
 
    my_stpcpy(new_alias= new_alias_buff, new_name);
 
5638
    DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
 
5639
    strmov(new_name_buff,new_name);
 
5640
    strmov(new_alias= new_alias_buff, new_name);
4481
5641
    if (lower_case_table_names)
4482
5642
    {
4483
5643
      if (lower_case_table_names != 2)
4503
5663
        if (find_temporary_table(thd,new_db,new_name_buff))
4504
5664
        {
4505
5665
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
4506
 
          return(true);
 
5666
          DBUG_RETURN(true);
4507
5667
        }
4508
5668
      }
4509
5669
      else
4510
5670
      {
4511
5671
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
4512
 
          return(true);
 
5672
          DBUG_RETURN(true);
4513
5673
        if (!name_lock)
4514
5674
        {
4515
5675
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
4516
 
          return(true);
 
5676
          DBUG_RETURN(true);
4517
5677
        }
4518
5678
 
4519
5679
        build_table_filename(new_name_buff, sizeof(new_name_buff),
4543
5703
    goto err;
4544
5704
  new_db_type= create_info->db_type;
4545
5705
 
4546
 
  if (new_db_type != old_db_type &&
 
5706
  if (new_db_type != old_db_type ||
4547
5707
      !table->file->can_switch_engines())
4548
5708
  {
4549
 
    assert(0);
4550
5709
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
4551
5710
    goto err;
4552
5711
  }
4554
5713
  if (create_info->row_type == ROW_TYPE_NOT_USED)
4555
5714
    create_info->row_type= table->s->row_type;
4556
5715
 
 
5716
  DBUG_PRINT("info", ("old type: %s  new type: %s",
 
5717
             ha_resolve_storage_engine_name(old_db_type),
 
5718
             ha_resolve_storage_engine_name(new_db_type)));
4557
5719
  if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
4558
5720
      ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
4559
5721
  {
 
5722
    DBUG_PRINT("info", ("doesn't support alter"));
4560
5723
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4561
5724
    goto err;
4562
5725
  }
4563
5726
 
4564
 
  thd->set_proc_info("setup");
 
5727
  thd_proc_info(thd, "setup");
4565
5728
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4566
5729
      !table->s->tmp_table) // no need to touch frm
4567
5730
  {
4571
5734
    case ENABLE:
4572
5735
      /*
4573
5736
        wait_while_table_is_used() ensures that table being altered is
4574
 
        opened only by this thread and that Table::TABLE_SHARE::version
4575
 
        of Table object corresponding to this table is 0.
 
5737
        opened only by this thread and that TABLE::TABLE_SHARE::version
 
5738
        of TABLE object corresponding to this table is 0.
4576
5739
        The latter guarantees that no DML statement will open this table
4577
 
        until ALTER Table finishes (i.e. until close_thread_tables())
 
5740
        until ALTER TABLE finishes (i.e. until close_thread_tables())
4578
5741
        while the fact that the table is still open gives us protection
4579
5742
        from concurrent DDL statements.
4580
5743
      */
4581
 
      pthread_mutex_lock(&LOCK_open);
 
5744
      VOID(pthread_mutex_lock(&LOCK_open));
4582
5745
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4583
 
      pthread_mutex_unlock(&LOCK_open);
 
5746
      VOID(pthread_mutex_unlock(&LOCK_open));
 
5747
      DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
4584
5748
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4585
5749
      /* COND_refresh will be signaled in close_thread_tables() */
4586
5750
      break;
4587
5751
    case DISABLE:
4588
 
      pthread_mutex_lock(&LOCK_open);
 
5752
      VOID(pthread_mutex_lock(&LOCK_open));
4589
5753
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4590
 
      pthread_mutex_unlock(&LOCK_open);
 
5754
      VOID(pthread_mutex_unlock(&LOCK_open));
4591
5755
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4592
5756
      /* COND_refresh will be signaled in close_thread_tables() */
4593
5757
      break;
4594
5758
    default:
4595
 
      assert(false);
 
5759
      DBUG_ASSERT(false);
4596
5760
      error= 0;
4597
5761
      break;
4598
5762
    }
4599
5763
    if (error == HA_ERR_WRONG_COMMAND)
4600
5764
    {
4601
5765
      error= 0;
4602
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5766
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4603
5767
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4604
5768
                          table->alias);
4605
5769
    }
4606
5770
 
4607
 
    pthread_mutex_lock(&LOCK_open);
 
5771
    VOID(pthread_mutex_lock(&LOCK_open));
4608
5772
    /*
4609
5773
      Unlike to the above case close_cached_table() below will remove ALL
4610
 
      instances of Table from table cache (it will also remove table lock
 
5774
      instances of TABLE from table cache (it will also remove table lock
4611
5775
      held by this thread). So to make actual table renaming and writing
4612
5776
      to binlog atomic we have to put them into the same critical section
4613
5777
      protected by LOCK_open mutex. This also removes gap for races between
4616
5780
 
4617
5781
    if (!error && (new_name != table_name || new_db != db))
4618
5782
    {
4619
 
      thd->set_proc_info("rename");
 
5783
      thd_proc_info(thd, "rename");
4620
5784
      /*
4621
5785
        Then do a 'simple' rename of the table. First we need to close all
4622
5786
        instances of 'source' table.
4642
5806
          error= -1;
4643
5807
        else if (0)
4644
5808
      {
4645
 
          mysql_rename_table(old_db_type, new_db, new_alias, db,
4646
 
                             table_name, 0);
 
5809
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
 
5810
                                  table_name, 0));
4647
5811
          error= -1;
4648
5812
      }
4649
5813
    }
4652
5816
    if (error == HA_ERR_WRONG_COMMAND)
4653
5817
  {
4654
5818
      error= 0;
4655
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5819
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4656
5820
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4657
5821
                          table->alias);
4658
5822
  }
4669
5833
    }
4670
5834
    if (name_lock)
4671
5835
      unlink_open_table(thd, name_lock, false);
4672
 
    pthread_mutex_unlock(&LOCK_open);
 
5836
    VOID(pthread_mutex_unlock(&LOCK_open));
4673
5837
    table_list->table= NULL;                    // For query cache
4674
 
    return(error);
 
5838
    DBUG_RETURN(error);
4675
5839
  }
4676
5840
 
4677
5841
  /* We have to do full alter table. */
4678
5842
 
4679
5843
    /*
4680
 
    If the old table had partitions and we are doing ALTER Table ...
 
5844
    If the old table had partitions and we are doing ALTER TABLE ...
4681
5845
    engine= <new_engine>, the new table must preserve the original
4682
5846
    partitioning. That means that the new engine is still the
4683
5847
    partitioning engine, not the engine specified in the parser.
4709
5873
 
4710
5874
  if (alter_info->build_method != HA_BUILD_OFFLINE)
4711
5875
  {
4712
 
    Table *altered_table= 0;
 
5876
    TABLE *altered_table= 0;
4713
5877
    HA_ALTER_INFO ha_alter_info;
4714
5878
    HA_ALTER_FLAGS ha_alter_flags;
4715
 
    uint32_t table_changes= IS_EQUAL_YES;
 
5879
    uint table_changes= IS_EQUAL_YES;
4716
5880
    bool need_copy_table= true;
4717
5881
    /* Check how much the tables differ. */
4718
5882
    if (compare_tables(thd, table, alter_info,
4721
5885
                       &ha_alter_info,
4722
5886
                       &table_changes))
4723
5887
    {
4724
 
      return(true);
 
5888
      DBUG_RETURN(true);
4725
5889
    }
4726
5890
 
4727
5891
    /*
4729
5893
      on-line.
4730
5894
    */
4731
5895
 
 
5896
#ifndef DBUG_OFF
 
5897
    {
 
5898
      char dbug_string[HA_MAX_ALTER_FLAGS+1];
 
5899
      ha_alter_flags.print(dbug_string);
 
5900
      DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
 
5901
                          need_copy_table, table_changes,
 
5902
                          (char *) dbug_string));
 
5903
    }
 
5904
#endif
4732
5905
 
4733
5906
    /*
4734
5907
      If table is not renamed, changed database and
4761
5934
        /*
4762
5935
          @todo: Currently we always acquire an exclusive name
4763
5936
          lock on the table metadata when performing fast or online
4764
 
          ALTER Table. In future we may consider this unnecessary,
 
5937
          ALTER TABLE. In future we may consider this unnecessary,
4765
5938
          and narrow the scope of the exclusive name lock to only
4766
5939
          cover manipulation with .frms. Storage engine API
4767
5940
          call check_if_supported_alter has provision for this
4783
5956
        close_temporary_table(thd, altered_table, 1, 1);
4784
5957
        goto err;
4785
5958
      }
 
5959
#ifndef DBUG_OFF
 
5960
      {
 
5961
        char dbug_string[HA_MAX_ALTER_FLAGS+1];
 
5962
        ha_alter_flags.print(dbug_string);
 
5963
        DBUG_PRINT("info", ("need_copy_table: %u, table_changes: %u, Real alter_flags:  %s",
 
5964
                            need_copy_table, table_changes,
 
5965
                            (char *) dbug_string));
 
5966
      }
 
5967
#endif
4786
5968
 
4787
5969
    }
4788
 
    /* TODO need to check if changes can be handled as fast ALTER Table */
 
5970
    /* TODO need to check if changes can be handled as fast ALTER TABLE */
4789
5971
    if (!altered_table)
4790
5972
      need_copy_table= true;
4791
5973
 
4825
6007
      close_temporary_table(thd, altered_table, 1, 1);
4826
6008
  }
4827
6009
 
4828
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4829
 
           current_pid, thd->thread_id);
 
6010
  my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
 
6011
              current_pid, thd->thread_id);
4830
6012
  /* Safety fix for innodb */
4831
6013
  if (lower_case_table_names)
4832
6014
    my_casedn_str(files_charset_info, tmp_name);
4843
6025
  /* Open the table so we need to copy the data to it. */
4844
6026
  if (table->s->tmp_table)
4845
6027
  {
4846
 
    TableList tbl;
4847
 
    memset(&tbl, 0, sizeof(tbl));
 
6028
    TABLE_LIST tbl;
 
6029
    bzero((void*) &tbl, sizeof(tbl));
4848
6030
    tbl.db= new_db;
4849
6031
    tbl.table_name= tbl.alias= tmp_name;
4850
6032
    /* Table is in thd->temporary_tables */
4851
 
    new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
 
6033
    new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
 
6034
                          MYSQL_LOCK_IGNORE_FLUSH);
4852
6035
  }
4853
6036
  else
4854
6037
  {
4865
6048
  /* Copy the data if necessary. */
4866
6049
  thd->count_cuted_fields= CHECK_FIELD_WARN;    // calc cuted fields
4867
6050
  thd->cuted_fields=0L;
4868
 
  thd->set_proc_info("copy to tmp table");
 
6051
  thd_proc_info(thd, "copy to tmp table");
4869
6052
  copied=deleted=0;
4870
6053
  /*
4871
6054
    We do not copy data for MERGE tables. Only the children have data.
4873
6056
  */
4874
6057
  if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
4875
6058
  {
4876
 
    /* We don't want update TIMESTAMP fields during ALTER Table. */
 
6059
    /* We don't want update TIMESTAMP fields during ALTER TABLE. */
4877
6060
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
4878
6061
    new_table->next_number_field=new_table->found_next_number_field;
4879
6062
    error= copy_data_between_tables(table, new_table,
4884
6067
  }
4885
6068
  else
4886
6069
  {
4887
 
    pthread_mutex_lock(&LOCK_open);
 
6070
    VOID(pthread_mutex_lock(&LOCK_open));
4888
6071
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4889
 
    pthread_mutex_unlock(&LOCK_open);
 
6072
    VOID(pthread_mutex_unlock(&LOCK_open));
4890
6073
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4891
6074
                            alter_info->keys_onoff);
4892
6075
    error= ha_autocommit_or_rollback(thd, 0);
4924
6107
      Note that MERGE tables do not have their children attached here.
4925
6108
    */
4926
6109
    intern_close_table(new_table);
4927
 
    free(new_table);
 
6110
    my_free(new_table,MYF(0));
4928
6111
  }
4929
 
  pthread_mutex_lock(&LOCK_open);
 
6112
  VOID(pthread_mutex_lock(&LOCK_open));
4930
6113
  if (error)
4931
6114
  {
4932
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4933
 
    pthread_mutex_unlock(&LOCK_open);
 
6115
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
6116
    VOID(pthread_mutex_unlock(&LOCK_open));
4934
6117
    goto err;
4935
6118
  }
4936
6119
 
4941
6124
       with exclusive name-locks.
4942
6125
    3) Rename the old table to a temp name, rename the new one to the
4943
6126
       old name.
4944
 
    4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
 
6127
    4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
4945
6128
       we reopen new version of table.
4946
6129
    5) Write statement to the binary log.
4947
 
    6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
 
6130
    6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
4948
6131
       remove name-locks from list of open tables and table cache.
4949
6132
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
4950
6133
       call to remove name-locks from table cache and list of open table.
4951
6134
  */
4952
6135
 
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);
 
6136
  thd_proc_info(thd, "rename result table");
 
6137
  my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
 
6138
              current_pid, thd->thread_id);
4956
6139
  if (lower_case_table_names)
4957
6140
    my_casedn_str(files_charset_info, old_name);
4958
6141
 
4967
6150
    mysql_rename_table(), because we just juggle with the FRM and nothing
4968
6151
    more. If we have an intermediate table, then we notify the SE that
4969
6152
    it should become the actual table. Later, we will recycle the old table.
4970
 
    However, in case of ALTER Table RENAME there might be no intermediate
 
6153
    However, in case of ALTER TABLE RENAME there might be no intermediate
4971
6154
    table. This is when the old and new tables are compatible, according to
4972
6155
    compare_table(). Then, we need one additional call to
4973
6156
    mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
4979
6162
                         FN_TO_IS_TMP))
4980
6163
  {
4981
6164
    error=1;
4982
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
6165
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4983
6166
  }
4984
6167
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
4985
6168
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
4986
6169
  {
4987
6170
    /* Try to get everything back. */
4988
6171
    error=1;
4989
 
    quick_rm_table(new_db_type,new_db,new_alias, 0);
4990
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4991
 
    mysql_rename_table(old_db_type, db, old_name, db, alias,
4992
 
                       FN_FROM_IS_TMP);
 
6172
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
 
6173
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
6174
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
 
6175
                            FN_FROM_IS_TMP));
4993
6176
  }
4994
6177
 
4995
6178
  if (error)
4998
6181
    goto err_with_placeholders;
4999
6182
  }
5000
6183
 
5001
 
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
 
6184
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
5002
6185
 
5003
6186
end_online:
5004
6187
  if (thd->locked_tables && new_name == table_name && new_db == db)
5009
6192
    if (error)
5010
6193
      goto err_with_placeholders;
5011
6194
  }
5012
 
  pthread_mutex_unlock(&LOCK_open);
5013
 
 
5014
 
  thd->set_proc_info("end");
5015
 
 
5016
 
  assert(!(mysql_bin_log.is_open() &&
 
6195
  VOID(pthread_mutex_unlock(&LOCK_open));
 
6196
 
 
6197
  thd_proc_info(thd, "end");
 
6198
 
 
6199
  DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
 
6200
 
 
6201
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
 
6202
                      thd->query, thd->query_length,
 
6203
                      db, table_name);
 
6204
 
 
6205
  DBUG_ASSERT(!(mysql_bin_log.is_open() &&
5017
6206
                thd->current_stmt_binlog_row_based &&
5018
6207
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
5019
6208
  write_bin_log(thd, true, thd->query, thd->query_length);
5026
6215
      shutdown. But we do not need to attach MERGE children.
5027
6216
    */
5028
6217
    char path[FN_REFLEN];
5029
 
    Table *t_table;
 
6218
    TABLE *t_table;
5030
6219
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
5031
6220
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
5032
6221
    if (t_table)
5033
6222
    {
5034
6223
      intern_close_table(t_table);
5035
 
      free(t_table);
 
6224
      my_free(t_table, MYF(0));
5036
6225
    }
5037
6226
    else
5038
 
      sql_print_warning(_("Could not open table %s.%s after rename\n"),
 
6227
      sql_print_warning("Could not open table %s.%s after rename\n",
5039
6228
                        new_db,table_name);
5040
6229
    ha_flush_logs(old_db_type);
5041
6230
  }
5044
6233
  if (thd->locked_tables && (new_name != table_name || new_db != db))
5045
6234
  {
5046
6235
    /*
5047
 
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
 
6236
      If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
5048
6237
      to remove placeholders for the old table and for the target table
5049
6238
      from the list of open tables and table cache. If we are not under
5050
6239
      LOCK TABLES we can rely on close_thread_tables() doing this job.
5056
6245
  }
5057
6246
 
5058
6247
end_temporary:
5059
 
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5060
 
           (ulong) (copied + deleted), (ulong) deleted,
5061
 
           (ulong) thd->cuted_fields);
 
6248
  my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 
6249
              (ulong) (copied + deleted), (ulong) deleted,
 
6250
              (ulong) thd->cuted_fields);
5062
6251
  my_ok(thd, copied + deleted, 0L, tmp_name);
5063
6252
  thd->some_tables_deleted=0;
5064
 
  return(false);
 
6253
  DBUG_RETURN(false);
5065
6254
 
5066
6255
err1:
5067
6256
  if (new_table)
5070
6259
    close_temporary_table(thd, new_table, 1, 1);
5071
6260
  }
5072
6261
  else
5073
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
6262
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
5074
6263
 
5075
6264
err:
5076
6265
  /*
5082
6271
  if (alter_info->error_if_not_empty && thd->row_count)
5083
6272
  {
5084
6273
    const char *f_val= 0;
5085
 
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
 
6274
    enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
5086
6275
    switch (alter_info->datetime_field->sql_type)
5087
6276
    {
5088
 
      case DRIZZLE_TYPE_NEWDATE:
 
6277
      case MYSQL_TYPE_DATE:
 
6278
      case MYSQL_TYPE_NEWDATE:
5089
6279
        f_val= "0000-00-00";
5090
 
        t_type= DRIZZLE_TIMESTAMP_DATE;
 
6280
        t_type= MYSQL_TIMESTAMP_DATE;
5091
6281
        break;
5092
 
      case DRIZZLE_TYPE_DATETIME:
 
6282
      case MYSQL_TYPE_DATETIME:
5093
6283
        f_val= "0000-00-00 00:00:00";
5094
 
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
 
6284
        t_type= MYSQL_TIMESTAMP_DATETIME;
5095
6285
        break;
5096
6286
      default:
5097
6287
        /* Shouldn't get here. */
5098
 
        assert(0);
 
6288
        DBUG_ASSERT(0);
5099
6289
    }
5100
6290
    bool save_abort_on_warning= thd->abort_on_warning;
5101
6291
    thd->abort_on_warning= true;
5102
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
6292
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
5103
6293
                                 f_val, strlength(f_val), t_type,
5104
6294
                                 alter_info->datetime_field->field_name);
5105
6295
    thd->abort_on_warning= save_abort_on_warning;
5110
6300
    unlink_open_table(thd, name_lock, false);
5111
6301
    pthread_mutex_unlock(&LOCK_open);
5112
6302
  }
5113
 
  return(true);
 
6303
  DBUG_RETURN(true);
5114
6304
 
5115
6305
err_with_placeholders:
5116
6306
  /*
5121
6311
  unlink_open_table(thd, table, false);
5122
6312
  if (name_lock)
5123
6313
    unlink_open_table(thd, name_lock, false);
5124
 
  pthread_mutex_unlock(&LOCK_open);
5125
 
  return(true);
 
6314
  VOID(pthread_mutex_unlock(&LOCK_open));
 
6315
  DBUG_RETURN(true);
5126
6316
}
5127
6317
/* mysql_alter_table */
5128
6318
 
5129
6319
static int
5130
 
copy_data_between_tables(Table *from,Table *to,
 
6320
copy_data_between_tables(TABLE *from,TABLE *to,
5131
6321
                         List<Create_field> &create,
5132
6322
                         bool ignore,
5133
 
                         uint32_t order_num, order_st *order,
 
6323
                         uint order_num, ORDER *order,
5134
6324
                         ha_rows *copied,
5135
6325
                         ha_rows *deleted,
5136
6326
                         enum enum_enable_or_disable keys_onoff,
5140
6330
  Copy_field *copy,*copy_end;
5141
6331
  ulong found_count,delete_count;
5142
6332
  THD *thd= current_thd;
5143
 
  uint32_t length= 0;
 
6333
  uint length= 0;
5144
6334
  SORT_FIELD *sortorder;
5145
6335
  READ_RECORD info;
5146
 
  TableList   tables;
 
6336
  TABLE_LIST   tables;
5147
6337
  List<Item>   fields;
5148
6338
  List<Item>   all_fields;
5149
6339
  ha_rows examined_rows;
5150
6340
  bool auto_increment_field_copied= 0;
5151
6341
  ulong save_sql_mode;
5152
 
  uint64_t prev_insert_id;
 
6342
  ulonglong prev_insert_id;
 
6343
  DBUG_ENTER("copy_data_between_tables");
5153
6344
 
5154
6345
  /*
5155
6346
    Turn off recovery logging since rollback of an alter table is to
5159
6350
  */
5160
6351
  error= ha_enable_transaction(thd, false);
5161
6352
  if (error)
5162
 
    return(-1);
 
6353
    DBUG_RETURN(-1);
5163
6354
  
5164
6355
  if (!(copy= new Copy_field[to->s->fields]))
5165
 
    return(-1);                         /* purecov: inspected */
 
6356
    DBUG_RETURN(-1);                            /* purecov: inspected */
5166
6357
 
5167
6358
  if (to->file->ha_external_lock(thd, F_WRLCK))
5168
 
    return(-1);
 
6359
    DBUG_RETURN(-1);
5169
6360
 
5170
6361
  /* We need external lock before we can disable/enable keys */
5171
6362
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5187
6378
    if (def->field)
5188
6379
    {
5189
6380
      if (*ptr == to->next_number_field)
 
6381
      {
5190
6382
        auto_increment_field_copied= true;
5191
 
 
 
6383
        /*
 
6384
          If we are going to copy contents of one auto_increment column to
 
6385
          another auto_increment column it is sensible to preserve zeroes.
 
6386
          This condition also covers case when we are don't actually alter
 
6387
          auto_increment column.
 
6388
        */
 
6389
        if (def->field == from->found_next_number_field)
 
6390
          thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
 
6391
      }
5192
6392
      (copy_end++)->set(*ptr,def->field,0);
5193
6393
    }
5194
6394
 
5200
6400
  {
5201
6401
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5202
6402
    {
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,
 
6403
      char warn_buff[MYSQL_ERRMSG_SIZE];
 
6404
      my_snprintf(warn_buff, sizeof(warn_buff), 
 
6405
                  "ORDER BY ignored as there is a user-defined clustered index"
 
6406
                  " in the table '%-.192s'", from->s->table_name.str);
 
6407
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5209
6408
                   warn_buff);
5210
6409
    }
5211
6410
    else
5212
6411
    {
5213
6412
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5214
6413
                                                MYF(MY_FAE | MY_ZEROFILL));
5215
 
      memset(&tables, 0, sizeof(tables));
 
6414
      bzero((char *) &tables, sizeof(tables));
5216
6415
      tables.table= from;
5217
6416
      tables.alias= tables.table_name= from->s->table_name.str;
5218
6417
      tables.db= from->s->db.str;
5265
6464
      copy_ptr->do_copy(copy_ptr);
5266
6465
    }
5267
6466
    prev_insert_id= to->file->next_insert_id;
5268
 
    update_virtual_fields_marked_for_write(to, false);
5269
6467
    error=to->file->ha_write_row(to->record[0]);
5270
6468
    to->auto_increment_field_not_null= false;
5271
6469
    if (error)
5275
6473
      {
5276
6474
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
5277
6475
         {
5278
 
           uint32_t key_nr= to->file->get_dup_key(error);
 
6476
           uint key_nr= to->file->get_dup_key(error);
5279
6477
           if ((int) key_nr >= 0)
5280
6478
           {
5281
6479
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
5332
6530
  to->file->ha_release_auto_increment();
5333
6531
  if (to->file->ha_external_lock(thd,F_UNLCK))
5334
6532
    error=1;
5335
 
  return(error > 0 ? -1 : 0);
 
6533
  DBUG_RETURN(error > 0 ? -1 : 0);
5336
6534
}
5337
6535
 
5338
6536
 
5347
6545
 RETURN
5348
6546
    Like mysql_alter_table().
5349
6547
*/
5350
 
bool mysql_recreate_table(THD *thd, TableList *table_list)
 
6548
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
5351
6549
{
5352
6550
  HA_CREATE_INFO create_info;
5353
6551
  Alter_info alter_info;
5354
6552
 
5355
 
  assert(!table_list->next_global);
 
6553
  DBUG_ENTER("mysql_recreate_table");
 
6554
  DBUG_ASSERT(!table_list->next_global);
5356
6555
  /*
5357
6556
    table_list->table has been closed and freed. Do not reference
5358
6557
    uninitialized data. open_tables() could fail.
5359
6558
  */
5360
6559
  table_list->table= NULL;
5361
6560
 
5362
 
  memset(&create_info, 0, sizeof(create_info));
 
6561
  bzero((char*) &create_info, sizeof(create_info));
5363
6562
  create_info.row_type=ROW_TYPE_NOT_USED;
5364
6563
  create_info.default_table_charset=default_charset_info;
5365
6564
  /* Force alter table to recreate table */
5366
6565
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5367
 
  return(mysql_alter_table(thd, NULL, NULL, &create_info,
 
6566
  DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
5368
6567
                                table_list, &alter_info, 0,
5369
 
                                (order_st *) 0, 0));
 
6568
                                (ORDER *) 0, 0));
5370
6569
}
5371
6570
 
5372
6571
 
5373
 
bool mysql_checksum_table(THD *thd, TableList *tables,
 
6572
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
5374
6573
                          HA_CHECK_OPT *check_opt)
5375
6574
{
5376
 
  TableList *table;
 
6575
  TABLE_LIST *table;
5377
6576
  List<Item> field_list;
5378
6577
  Item *item;
5379
6578
  Protocol *protocol= thd->protocol;
 
6579
  DBUG_ENTER("mysql_checksum_table");
5380
6580
 
5381
6581
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5382
6582
  item->maybe_null= 1;
5383
 
  field_list.push_back(item= new Item_int("Checksum", (int64_t) 1,
 
6583
  field_list.push_back(item= new Item_int("Checksum", (longlong) 1,
5384
6584
                                          MY_INT64_NUM_DECIMAL_DIGITS));
5385
6585
  item->maybe_null= 1;
5386
6586
  if (protocol->send_fields(&field_list,
5387
6587
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
5388
 
    return(true);
 
6588
    DBUG_RETURN(true);
5389
6589
 
5390
6590
  /* Open one table after the other to keep lock time as short as possible. */
5391
6591
  for (table= tables; table; table= table->next_local)
5392
6592
  {
5393
6593
    char table_name[NAME_LEN*2+2];
5394
 
    Table *t;
 
6594
    TABLE *t;
5395
6595
 
5396
 
    strxmov(table_name, table->db ,".", table->table_name, NULL);
 
6596
    strxmov(table_name, table->db ,".", table->table_name, NullS);
5397
6597
 
5398
6598
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5399
6599
    thd->clear_error();                 // these errors shouldn't get client
5411
6611
    {
5412
6612
      if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
5413
6613
          !(check_opt->flags & T_EXTEND))
5414
 
        protocol->store((uint64_t)t->file->checksum());
 
6614
        protocol->store((ulonglong)t->file->checksum());
5415
6615
      else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
5416
6616
               (check_opt->flags & T_QUICK))
5417
6617
        protocol->store_null();
5419
6619
      {
5420
6620
        /* calculating table's checksum */
5421
6621
        ha_checksum crc= 0;
5422
 
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
 
6622
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
5423
6623
 
5424
6624
        t->use_all_columns();
5425
6625
 
5447
6647
              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
5448
6648
            }
5449
6649
 
5450
 
            for (uint32_t i= 0; i < t->s->fields; i++ )
 
6650
            for (uint i= 0; i < t->s->fields; i++ )
5451
6651
            {
5452
6652
              Field *f= t->field[i];
5453
 
              if ((f->type() == DRIZZLE_TYPE_BLOB) ||
5454
 
                  (f->type() == DRIZZLE_TYPE_VARCHAR))
 
6653
              if ((f->type() == MYSQL_TYPE_BLOB) ||
 
6654
                  (f->type() == MYSQL_TYPE_VARCHAR))
5455
6655
              {
5456
6656
                String tmp;
5457
6657
                f->val_str(&tmp);
5458
 
                row_crc= my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
 
6658
                row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
5459
6659
              }
5460
6660
              else
5461
6661
                row_crc= my_checksum(row_crc, f->ptr,
5464
6664
 
5465
6665
            crc+= row_crc;
5466
6666
          }
5467
 
          protocol->store((uint64_t)crc);
 
6667
          protocol->store((ulonglong)crc);
5468
6668
          t->file->ha_rnd_end();
5469
6669
        }
5470
6670
      }
5477
6677
  }
5478
6678
 
5479
6679
  my_eof(thd);
5480
 
  return(false);
 
6680
  DBUG_RETURN(false);
5481
6681
 
5482
6682
 err:
5483
6683
  close_thread_tables(thd);                     // Shouldn't be needed
5484
6684
  if (table)
5485
6685
    table->table=0;
5486
 
  return(true);
 
6686
  DBUG_RETURN(true);
5487
6687
}
5488
6688
 
5489
6689
static bool check_engine(THD *thd, const char *table_name,
5498
6698
 
5499
6699
  if (req_engine && req_engine != *new_engine)
5500
6700
  {
5501
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
6701
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
5502
6702
                       ER_WARN_USING_OTHER_HANDLER,
5503
6703
                       ER(ER_WARN_USING_OTHER_HANDLER),
5504
6704
                       ha_resolve_storage_engine_name(*new_engine),