~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* drop and alter of tables */
17
17
 
18
 
#include "mysql_priv.h"
19
 
#include <hash.h>
20
 
#include <myisam.h>
21
 
#include <my_dir.h>
22
 
#include "sql_show.h"
 
18
#include <drizzled/server_includes.h>
 
19
#include <storage/myisam/myisam.h>
 
20
#include <drizzled/sql_show.h>
 
21
#include <drizzled/drizzled_error_messages.h>
 
22
#include <libdrizzle/gettext.h>
23
23
 
24
24
int creating_table= 0;        // How many mysql_create_table are running
25
25
 
27
27
 
28
28
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
29
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
30
 
static int copy_data_between_tables(TABLE *from,TABLE *to,
 
30
static int copy_data_between_tables(Table *from,Table *to,
31
31
                                    List<Create_field> &create, bool ignore,
32
 
                                    uint order_num, ORDER *order,
 
32
                                    uint32_t order_num, order_st *order,
33
33
                                    ha_rows *copied,ha_rows *deleted,
34
34
                                    enum enum_enable_or_disable keys_onoff,
35
35
                                    bool error_if_not_empty);
40
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
41
41
                           Alter_info *alter_info,
42
42
                           bool tmp_table,
43
 
                               uint *db_options,
 
43
                               uint32_t *db_options,
44
44
                               handler *file, KEY **key_info_buffer,
45
 
                               uint *key_count, int select_field_count);
 
45
                               uint32_t *key_count, int select_field_count);
46
46
static bool
47
 
mysql_prepare_alter_table(THD *thd, TABLE *table,
 
47
mysql_prepare_alter_table(THD *thd, Table *table,
48
48
                          HA_CREATE_INFO *create_info,
49
49
                          Alter_info *alter_info);
50
50
 
60
60
  RETURN
61
61
    Table name length.
62
62
*/
63
 
uint filename_to_tablename(const char *from, char *to, uint to_length)
 
63
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
64
64
{
65
 
  uint errors;
66
 
  uint res;
 
65
  uint32_t errors;
 
66
  uint32_t res;
67
67
 
68
68
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
69
69
  {
70
70
    /* Temporary table name. */
71
 
    res= (strnmov(to, from, to_length) - to);
 
71
    res= (my_stpncpy(to, from, to_length) - to);
72
72
  }
73
73
  else
74
74
  {
76
76
                    system_charset_info,  to, to_length, &errors);
77
77
    if (errors) // Old 5.0 name
78
78
    {
79
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
 
79
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NULL) -
80
80
            to);
81
 
      sql_print_error("Invalid (old?) table or database name '%s'", from);
82
 
      /*
83
 
        TODO: add a stored procedure for fix table and database names,
84
 
        and mention its name in error log.
85
 
      */
 
81
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
86
82
    }
87
83
  }
88
84
 
103
99
    File name length.
104
100
*/
105
101
 
106
 
uint tablename_to_filename(const char *from, char *to, uint to_length)
 
102
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
107
103
{
108
 
  uint errors, length;
 
104
  uint32_t errors, length;
109
105
 
110
106
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
111
107
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
147
143
    'db' is always converted.
148
144
    'ext' is not converted.
149
145
 
150
 
    The conversion suppression is required for ALTER TABLE. This
 
146
    The conversion suppression is required for ALTER Table. This
151
147
    statement creates intermediate tables. These are regular
152
148
    (non-temporary) tables with a temporary name. Their path names must
153
149
    be derivable from the table name. So we cannot use
157
153
    path length
158
154
*/
159
155
 
160
 
uint build_table_filename(char *buff, size_t bufflen, const char *db,
161
 
                          const char *table_name, const char *ext, uint flags)
 
156
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
 
157
                          const char *table_name, const char *ext, uint32_t flags)
162
158
{
163
159
  char dbbuff[FN_REFLEN];
164
160
  char tbbuff[FN_REFLEN];
165
161
 
166
162
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
167
 
    strnmov(tbbuff, table_name, sizeof(tbbuff));
 
163
    my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
168
164
  else
169
 
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
 
165
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
170
166
 
171
 
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
 
167
  tablename_to_filename(db, dbbuff, sizeof(dbbuff));
172
168
 
173
169
  char *end = buff + bufflen;
174
170
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
175
 
  char *pos = strnmov(buff, mysql_data_home, bufflen);
 
171
  char *pos = my_stpncpy(buff, mysql_data_home, bufflen);
176
172
  int rootdir_len= strlen(FN_ROOTDIR);
177
173
  if (pos - rootdir_len >= buff &&
178
174
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
179
 
    pos= strnmov(pos, FN_ROOTDIR, end - pos);
180
 
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
 
175
    pos= my_stpncpy(pos, FN_ROOTDIR, end - pos);
 
176
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NULL);
181
177
#ifdef USE_SYMDIR
182
178
  unpack_dirname(buff, buff);
183
179
  pos= strend(buff);
184
180
#endif
185
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
 
181
  pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
186
182
 
187
183
  return(pos - buff);
188
184
}
206
202
    path length
207
203
*/
208
204
 
209
 
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
205
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
210
206
{
211
207
 
212
 
  char *p= strnmov(buff, mysql_tmpdir, bufflen);
 
208
  char *p= my_stpncpy(buff, mysql_tmpdir, bufflen);
213
209
  snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
214
210
              tmp_file_prefix, current_pid,
215
211
              thd->thread_id, thd->tmp_table++, reg_ext);
220
216
    my_casedn_str(files_charset_info, p);
221
217
  }
222
218
 
223
 
  uint length= unpack_filename(buff, buff);
 
219
  uint32_t length= unpack_filename(buff, buff);
224
220
  return(length);
225
221
}
226
222
 
227
223
/*
228
 
--------------------------------------------------------------------------
229
 
 
230
 
   MODULE: DDL log
231
 
   -----------------
232
 
 
233
 
   This module is used to ensure that we can recover from crashes that occur
234
 
   in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
235
 
   We need to ensure that both t1 and t2 are dropped and not only t1 and
236
 
   also that each table drop is entirely done and not "half-baked".
237
 
 
238
 
   To support this we create log entries for each meta-data statement in the
239
 
   ddl log while we are executing. These entries are dropped when the
240
 
   operation is completed.
241
 
 
242
 
   At recovery those entries that were not completed will be executed.
243
 
 
244
 
   There is only one ddl log in the system and it is protected by a mutex
245
 
   and there is a global struct that contains information about its current
246
 
   state.
247
 
 
248
 
   History:
249
 
   First version written in 2006 by Mikael Ronstrom
250
 
--------------------------------------------------------------------------
251
 
*/
252
 
 
253
 
 
254
 
struct st_global_ddl_log
255
 
{
256
 
  /*
257
 
    We need to adjust buffer size to be able to handle downgrades/upgrades
258
 
    where IO_SIZE has changed. We'll set the buffer size such that we can
259
 
    handle that the buffer size was upto 4 times bigger in the version
260
 
    that wrote the DDL log.
261
 
  */
262
 
  char file_entry_buf[4*IO_SIZE];
263
 
  char file_name_str[FN_REFLEN];
264
 
  char *file_name;
265
 
  DDL_LOG_MEMORY_ENTRY *first_free;
266
 
  DDL_LOG_MEMORY_ENTRY *first_used;
267
 
  uint num_entries;
268
 
  File file_id;
269
 
  uint name_len;
270
 
  uint io_size;
271
 
  bool inited;
272
 
  bool do_release;
273
 
  bool recovery_phase;
274
 
  st_global_ddl_log() : inited(false), do_release(false) {}
275
 
};
276
 
 
277
 
st_global_ddl_log global_ddl_log;
278
 
 
279
 
pthread_mutex_t LOCK_gdl;
280
 
 
281
 
#define DDL_LOG_ENTRY_TYPE_POS 0
282
 
#define DDL_LOG_ACTION_TYPE_POS 1
283
 
#define DDL_LOG_PHASE_POS 2
284
 
#define DDL_LOG_NEXT_ENTRY_POS 4
285
 
#define DDL_LOG_NAME_POS 8
286
 
 
287
 
#define DDL_LOG_NUM_ENTRY_POS 0
288
 
#define DDL_LOG_NAME_LEN_POS 4
289
 
#define DDL_LOG_IO_SIZE_POS 8
290
 
 
291
 
/*
292
 
  Read one entry from ddl log file
293
 
  SYNOPSIS
294
 
    read_ddl_log_file_entry()
295
 
    entry_no                     Entry number to read
296
 
  RETURN VALUES
297
 
    true                         Error
298
 
    false                        Success
299
 
*/
300
 
 
301
 
static bool read_ddl_log_file_entry(uint entry_no)
302
 
{
303
 
  bool error= false;
304
 
  File file_id= global_ddl_log.file_id;
305
 
  uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
306
 
  ssize_t io_size= (ssize_t)global_ddl_log.io_size;
307
 
  
308
 
  if (pread(file_id, file_entry_buf, io_size, io_size * entry_no) != io_size)
309
 
    error= true;
310
 
  return(error);
311
 
}
312
 
 
313
 
 
314
 
/*
315
 
  Write one entry from ddl log file
316
 
  SYNOPSIS
317
 
    write_ddl_log_file_entry()
318
 
    entry_no                     Entry number to read
319
 
  RETURN VALUES
320
 
    true                         Error
321
 
    false                        Success
322
 
*/
323
 
 
324
 
static bool write_ddl_log_file_entry(uint entry_no)
325
 
{
326
 
  bool error= false;
327
 
  File file_id= global_ddl_log.file_id;
328
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
329
 
 
330
 
  if (pwrite(file_id, (uchar*)file_entry_buf,
331
 
                IO_SIZE, IO_SIZE * entry_no) != IO_SIZE)
332
 
    error= true;
333
 
  return(error);
334
 
}
335
 
 
336
 
 
337
 
/*
338
 
  Write ddl log header
339
 
  SYNOPSIS
340
 
    write_ddl_log_header()
341
 
  RETURN VALUES
342
 
    true                      Error
343
 
    false                     Success
344
 
*/
345
 
 
346
 
static bool write_ddl_log_header()
347
 
{
348
 
  uint16 const_var;
349
 
  bool error= false;
350
 
 
351
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
352
 
            global_ddl_log.num_entries);
353
 
  const_var= FN_LEN;
354
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
355
 
            (ulong) const_var);
356
 
  const_var= IO_SIZE;
357
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
358
 
            (ulong) const_var);
359
 
  if (write_ddl_log_file_entry(0UL))
360
 
  {
361
 
    sql_print_error("Error writing ddl log header");
362
 
    return(true);
363
 
  }
364
 
  VOID(sync_ddl_log());
365
 
  return(error);
366
 
}
367
 
 
368
 
 
369
 
/*
370
 
  Create ddl log file name
371
 
  SYNOPSIS
372
 
    create_ddl_log_file_name()
373
 
    file_name                   Filename setup
374
 
  RETURN VALUES
375
 
    NONE
376
 
*/
377
 
 
378
 
static inline void create_ddl_log_file_name(char *file_name)
379
 
{
380
 
  strxmov(file_name, mysql_data_home, "/", "ddl_log.log", NullS);
381
 
}
382
 
 
383
 
 
384
 
/*
385
 
  Read header of ddl log file
386
 
  SYNOPSIS
387
 
    read_ddl_log_header()
388
 
  RETURN VALUES
389
 
    > 0                  Last entry in ddl log
390
 
    0                    No entries in ddl log
391
 
  DESCRIPTION
392
 
    When we read the ddl log header we get information about maximum sizes
393
 
    of names in the ddl log and we also get information about the number
394
 
    of entries in the ddl log.
395
 
*/
396
 
 
397
 
static uint read_ddl_log_header()
398
 
{
399
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
400
 
  char file_name[FN_REFLEN];
401
 
  uint entry_no;
402
 
  bool successful_open= false;
403
 
 
404
 
  create_ddl_log_file_name(file_name);
405
 
  if ((global_ddl_log.file_id= my_open(file_name,
406
 
                                        O_RDWR | O_BINARY, MYF(0))) >= 0)
407
 
  {
408
 
    if (read_ddl_log_file_entry(0UL))
409
 
    {
410
 
      /* Write message into error log */
411
 
      sql_print_error("Failed to read ddl log file in recovery");
412
 
    }
413
 
    else
414
 
      successful_open= true;
415
 
  }
416
 
  entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
417
 
  global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
418
 
  if (successful_open)
419
 
  {
420
 
    global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
421
 
    assert(global_ddl_log.io_size <=
422
 
                sizeof(global_ddl_log.file_entry_buf));
423
 
  }
424
 
  else
425
 
  {
426
 
    entry_no= 0;
427
 
  }
428
 
  global_ddl_log.first_free= NULL;
429
 
  global_ddl_log.first_used= NULL;
430
 
  global_ddl_log.num_entries= 0;
431
 
  VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
432
 
  global_ddl_log.do_release= true;
433
 
  return(entry_no);
434
 
}
435
 
 
436
 
 
437
 
/*
438
 
  Read a ddl log entry
439
 
  SYNOPSIS
440
 
    read_ddl_log_entry()
441
 
    read_entry               Number of entry to read
442
 
    out:entry_info           Information from entry
443
 
  RETURN VALUES
444
 
    true                     Error
445
 
    false                    Success
446
 
  DESCRIPTION
447
 
    Read a specified entry in the ddl log
448
 
*/
449
 
 
450
 
bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
451
 
{
452
 
  char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
453
 
  uint inx;
454
 
  uchar single_char;
455
 
 
456
 
  if (read_ddl_log_file_entry(read_entry))
457
 
  {
458
 
    return(true);
459
 
  }
460
 
  ddl_log_entry->entry_pos= read_entry;
461
 
  single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
462
 
  ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
463
 
  single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
464
 
  ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
465
 
  ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
466
 
  ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
467
 
  ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
468
 
  inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
469
 
  ddl_log_entry->from_name= &file_entry_buf[inx];
470
 
  inx+= global_ddl_log.name_len;
471
 
  ddl_log_entry->handler_name= &file_entry_buf[inx];
472
 
  return(false);
473
 
}
474
 
 
475
 
 
476
 
/*
477
 
  Initialise ddl log
478
 
  SYNOPSIS
479
 
    init_ddl_log()
480
 
 
481
 
  DESCRIPTION
482
 
    Write the header of the ddl log file and length of names. Also set
483
 
    number of entries to zero.
484
 
 
485
 
  RETURN VALUES
486
 
    true                     Error
487
 
    false                    Success
488
 
*/
489
 
 
490
 
static bool init_ddl_log()
491
 
{
492
 
  char file_name[FN_REFLEN];
493
 
 
494
 
  if (global_ddl_log.inited)
495
 
    goto end;
496
 
 
497
 
  global_ddl_log.io_size= IO_SIZE;
498
 
  create_ddl_log_file_name(file_name);
499
 
  if ((global_ddl_log.file_id= my_create(file_name,
500
 
                                         CREATE_MODE,
501
 
                                         O_RDWR | O_TRUNC | O_BINARY,
502
 
                                         MYF(MY_WME))) < 0)
503
 
  {
504
 
    /* Couldn't create ddl log file, this is serious error */
505
 
    sql_print_error("Failed to open ddl log file");
506
 
    return(true);
507
 
  }
508
 
  global_ddl_log.inited= true;
509
 
  if (write_ddl_log_header())
510
 
  {
511
 
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
512
 
    global_ddl_log.inited= false;
513
 
    return(true);
514
 
  }
515
 
 
516
 
end:
517
 
  return(false);
518
 
}
519
 
 
520
 
 
521
 
/*
522
 
  Execute one action in a ddl log entry
523
 
  SYNOPSIS
524
 
    execute_ddl_log_action()
525
 
    ddl_log_entry              Information in action entry to execute
526
 
  RETURN VALUES
527
 
    true                       Error
528
 
    false                      Success
529
 
*/
530
 
 
531
 
static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
532
 
{
533
 
  bool frm_action= false;
534
 
  LEX_STRING handler_name;
535
 
  handler *file= NULL;
536
 
  MEM_ROOT mem_root;
537
 
  int error= true;
538
 
  char to_path[FN_REFLEN];
539
 
  char from_path[FN_REFLEN];
540
 
  handlerton *hton;
541
 
 
542
 
  if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
543
 
  {
544
 
    return(false);
545
 
  }
546
 
  handler_name.str= (char*)ddl_log_entry->handler_name;
547
 
  handler_name.length= strlen(ddl_log_entry->handler_name);
548
 
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 
549
 
  if (!strcmp(ddl_log_entry->handler_name, reg_ext))
550
 
    frm_action= true;
551
 
  else
552
 
  {
553
 
    plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
554
 
    if (!plugin)
555
 
    {
556
 
      my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
557
 
      goto error;
558
 
    }
559
 
    hton= plugin_data(plugin, handlerton*);
560
 
    file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
561
 
    if (!file)
562
 
    {
563
 
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
564
 
      goto error;
565
 
    }
566
 
  }
567
 
  switch (ddl_log_entry->action_type)
568
 
  {
569
 
    case DDL_LOG_REPLACE_ACTION:
570
 
    case DDL_LOG_DELETE_ACTION:
571
 
    {
572
 
      if (ddl_log_entry->phase == 0)
573
 
      {
574
 
        if (frm_action)
575
 
        {
576
 
          strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
577
 
          if ((error= my_delete(to_path, MYF(MY_WME))))
578
 
          {
579
 
            if (my_errno != ENOENT)
580
 
              break;
581
 
          }
582
 
        }
583
 
        else
584
 
        {
585
 
          if ((error= file->ha_delete_table(ddl_log_entry->name)))
586
 
          {
587
 
            if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
588
 
              break;
589
 
          }
590
 
        }
591
 
        if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
592
 
          break;
593
 
        VOID(sync_ddl_log());
594
 
        error= false;
595
 
        if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
596
 
          break;
597
 
      }
598
 
      assert(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
599
 
      /*
600
 
        Fall through and perform the rename action of the replace
601
 
        action. We have already indicated the success of the delete
602
 
        action in the log entry by stepping up the phase.
603
 
      */
604
 
    }
605
 
    case DDL_LOG_RENAME_ACTION:
606
 
    {
607
 
      error= true;
608
 
      if (frm_action)
609
 
      {
610
 
        strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
611
 
        strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
612
 
        if (my_rename(from_path, to_path, MYF(MY_WME)))
613
 
          break;
614
 
      }
615
 
      else
616
 
      {
617
 
        if (file->ha_rename_table(ddl_log_entry->from_name,
618
 
                                  ddl_log_entry->name))
619
 
          break;
620
 
      }
621
 
      if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
622
 
        break;
623
 
      VOID(sync_ddl_log());
624
 
      error= false;
625
 
      break;
626
 
    }
627
 
    default:
628
 
      assert(0);
629
 
      break;
630
 
  }
631
 
  delete file;
632
 
error:
633
 
  free_root(&mem_root, MYF(0)); 
634
 
  return(error);
635
 
}
636
 
 
637
 
 
638
 
/*
639
 
  Get a free entry in the ddl log
640
 
  SYNOPSIS
641
 
    get_free_ddl_log_entry()
642
 
    out:active_entry                A ddl log memory entry returned
643
 
  RETURN VALUES
644
 
    true                       Error
645
 
    false                      Success
646
 
*/
647
 
 
648
 
static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
649
 
                                   bool *write_header)
650
 
{
651
 
  DDL_LOG_MEMORY_ENTRY *used_entry;
652
 
  DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
653
 
 
654
 
  if (global_ddl_log.first_free == NULL)
655
 
  {
656
 
    if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
657
 
                              sizeof(DDL_LOG_MEMORY_ENTRY), MYF(MY_WME))))
658
 
    {
659
 
      sql_print_error("Failed to allocate memory for ddl log free list");
660
 
      return(true);
661
 
    }
662
 
    global_ddl_log.num_entries++;
663
 
    used_entry->entry_pos= global_ddl_log.num_entries;
664
 
    *write_header= true;
665
 
  }
666
 
  else
667
 
  {
668
 
    used_entry= global_ddl_log.first_free;
669
 
    global_ddl_log.first_free= used_entry->next_log_entry;
670
 
    *write_header= false;
671
 
  }
672
 
  /*
673
 
    Move from free list to used list
674
 
  */
675
 
  used_entry->next_log_entry= first_used;
676
 
  used_entry->prev_log_entry= NULL;
677
 
  global_ddl_log.first_used= used_entry;
678
 
  if (first_used)
679
 
    first_used->prev_log_entry= used_entry;
680
 
 
681
 
  *active_entry= used_entry;
682
 
  return(false);
683
 
}
684
 
 
685
 
 
686
 
/*
687
 
  External interface methods for the DDL log Module
688
 
  ---------------------------------------------------
689
 
*/
690
 
 
691
 
/*
692
 
  SYNOPSIS
693
 
    write_ddl_log_entry()
694
 
    ddl_log_entry         Information about log entry
695
 
    out:entry_written     Entry information written into   
696
 
 
697
 
  RETURN VALUES
698
 
    true                      Error
699
 
    false                     Success
700
 
 
701
 
  DESCRIPTION
702
 
    A careful write of the ddl log is performed to ensure that we can
703
 
    handle crashes occurring during CREATE and ALTER TABLE processing.
704
 
*/
705
 
 
706
 
bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
707
 
                         DDL_LOG_MEMORY_ENTRY **active_entry)
708
 
{
709
 
  bool error, write_header;
710
 
 
711
 
  if (init_ddl_log())
712
 
  {
713
 
    return(true);
714
 
  }
715
 
  global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
716
 
                                    (char)DDL_LOG_ENTRY_CODE;
717
 
  global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
718
 
                                    (char)ddl_log_entry->action_type;
719
 
  global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
720
 
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
721
 
            ddl_log_entry->next_entry);
722
 
  assert(strlen(ddl_log_entry->name) < FN_LEN);
723
 
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
724
 
          ddl_log_entry->name, FN_LEN - 1);
725
 
  if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
726
 
      ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
727
 
  {
728
 
    assert(strlen(ddl_log_entry->from_name) < FN_LEN);
729
 
    strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
730
 
          ddl_log_entry->from_name, FN_LEN - 1);
731
 
  }
732
 
  else
733
 
    global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
734
 
  assert(strlen(ddl_log_entry->handler_name) < FN_LEN);
735
 
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
736
 
          ddl_log_entry->handler_name, FN_LEN - 1);
737
 
  if (get_free_ddl_log_entry(active_entry, &write_header))
738
 
  {
739
 
    return(true);
740
 
  }
741
 
  error= false;
742
 
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
743
 
  {
744
 
    error= true;
745
 
    sql_print_error("Failed to write entry_no = %u",
746
 
                    (*active_entry)->entry_pos);
747
 
  }
748
 
  if (write_header && !error)
749
 
  {
750
 
    VOID(sync_ddl_log());
751
 
    if (write_ddl_log_header())
752
 
      error= true;
753
 
  }
754
 
  if (error)
755
 
    release_ddl_log_memory_entry(*active_entry);
756
 
  return(error);
757
 
}
758
 
 
759
 
 
760
 
/*
761
 
  Write final entry in the ddl log
762
 
  SYNOPSIS
763
 
    write_execute_ddl_log_entry()
764
 
    first_entry                    First entry in linked list of entries
765
 
                                   to execute, if 0 = NULL it means that
766
 
                                   the entry is removed and the entries
767
 
                                   are put into the free list.
768
 
    complete                       Flag indicating we are simply writing
769
 
                                   info about that entry has been completed
770
 
    in:out:active_entry            Entry to execute, 0 = NULL if the entry
771
 
                                   is written first time and needs to be
772
 
                                   returned. In this case the entry written
773
 
                                   is returned in this parameter
774
 
  RETURN VALUES
775
 
    true                           Error
776
 
    false                          Success
777
 
 
778
 
  DESCRIPTION
779
 
    This is the last write in the ddl log. The previous log entries have
780
 
    already been written but not yet synched to disk.
781
 
    We write a couple of log entries that describes action to perform.
782
 
    This entries are set-up in a linked list, however only when a first
783
 
    execute entry is put as the first entry these will be executed.
784
 
    This routine writes this first 
785
 
*/ 
786
 
 
787
 
bool write_execute_ddl_log_entry(uint first_entry,
788
 
                                 bool complete,
789
 
                                 DDL_LOG_MEMORY_ENTRY **active_entry)
790
 
{
791
 
  bool write_header= false;
792
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
793
 
 
794
 
  if (init_ddl_log())
795
 
  {
796
 
    return(true);
797
 
  }
798
 
  if (!complete)
799
 
  {
800
 
    /*
801
 
      We haven't synched the log entries yet, we synch them now before
802
 
      writing the execute entry. If complete is true we haven't written
803
 
      any log entries before, we are only here to write the execute
804
 
      entry to indicate it is done.
805
 
    */
806
 
    VOID(sync_ddl_log());
807
 
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
808
 
  }
809
 
  else
810
 
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
811
 
  file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
812
 
  file_entry_buf[DDL_LOG_PHASE_POS]= 0;
813
 
  int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
814
 
  file_entry_buf[DDL_LOG_NAME_POS]= 0;
815
 
  file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
816
 
  file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
817
 
  if (!(*active_entry))
818
 
  {
819
 
    if (get_free_ddl_log_entry(active_entry, &write_header))
820
 
    {
821
 
      return(true);
822
 
    }
823
 
  }
824
 
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
825
 
  {
826
 
    sql_print_error("Error writing execute entry in ddl log");
827
 
    release_ddl_log_memory_entry(*active_entry);
828
 
    return(true);
829
 
  }
830
 
  VOID(sync_ddl_log());
831
 
  if (write_header)
832
 
  {
833
 
    if (write_ddl_log_header())
834
 
    {
835
 
      release_ddl_log_memory_entry(*active_entry);
836
 
      return(true);
837
 
    }
838
 
  }
839
 
  return(false);
840
 
}
841
 
 
842
 
 
843
 
/*
844
 
  For complex rename operations we need to deactivate individual entries.
845
 
  SYNOPSIS
846
 
    deactivate_ddl_log_entry()
847
 
    entry_no                      Entry position of record to change
848
 
  RETURN VALUES
849
 
    true                         Error
850
 
    false                        Success
851
 
  DESCRIPTION
852
 
    During replace operations where we start with an existing table called
853
 
    t1 and a replacement table called t1#temp or something else and where
854
 
    we want to delete t1 and rename t1#temp to t1 this is not possible to
855
 
    do in a safe manner unless the ddl log is informed of the phases in
856
 
    the change.
857
 
 
858
 
    Delete actions are 1-phase actions that can be ignored immediately after
859
 
    being executed.
860
 
    Rename actions from x to y is also a 1-phase action since there is no
861
 
    interaction with any other handlers named x and y.
862
 
    Replace action where drop y and x -> y happens needs to be a two-phase
863
 
    action. Thus the first phase will drop y and the second phase will
864
 
    rename x -> y.
865
 
*/
866
 
 
867
 
bool deactivate_ddl_log_entry(uint entry_no)
868
 
{
869
 
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
870
 
 
871
 
  if (!read_ddl_log_file_entry(entry_no))
872
 
  {
873
 
    if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
874
 
    {
875
 
      if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
876
 
          file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
877
 
          (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
878
 
           file_entry_buf[DDL_LOG_PHASE_POS] == 1))
879
 
        file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
880
 
      else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
881
 
      {
882
 
        assert(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
883
 
        file_entry_buf[DDL_LOG_PHASE_POS]= 1;
884
 
      }
885
 
      else
886
 
      {
887
 
        assert(0);
888
 
      }
889
 
      if (write_ddl_log_file_entry(entry_no))
890
 
      {
891
 
        sql_print_error("Error in deactivating log entry. Position = %u",
892
 
                        entry_no);
893
 
        return(true);
894
 
      }
895
 
    }
896
 
  }
897
 
  else
898
 
  {
899
 
    sql_print_error("Failed in reading entry before deactivating it");
900
 
    return(true);
901
 
  }
902
 
  return(false);
903
 
}
904
 
 
905
 
 
906
 
/*
907
 
  Sync ddl log file
908
 
  SYNOPSIS
909
 
    sync_ddl_log()
910
 
  RETURN VALUES
911
 
    true                      Error
912
 
    false                     Success
913
 
*/
914
 
 
915
 
bool sync_ddl_log()
916
 
{
917
 
  bool error= false;
918
 
 
919
 
  if ((!global_ddl_log.recovery_phase) &&
920
 
      init_ddl_log())
921
 
  {
922
 
    return(true);
923
 
  }
924
 
  if (my_sync(global_ddl_log.file_id, MYF(0)))
925
 
  {
926
 
    /* Write to error log */
927
 
    sql_print_error("Failed to sync ddl log");
928
 
    error= true;
929
 
  }
930
 
  return(error);
931
 
}
932
 
 
933
 
 
934
 
/*
935
 
  Release a log memory entry
936
 
  SYNOPSIS
937
 
    release_ddl_log_memory_entry()
938
 
    log_memory_entry                Log memory entry to release
939
 
  RETURN VALUES
940
 
    NONE
941
 
*/
942
 
 
943
 
void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
944
 
{
945
 
  DDL_LOG_MEMORY_ENTRY *first_free= global_ddl_log.first_free;
946
 
  DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
947
 
  DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
948
 
 
949
 
  global_ddl_log.first_free= log_entry;
950
 
  log_entry->next_log_entry= first_free;
951
 
 
952
 
  if (prev_log_entry)
953
 
    prev_log_entry->next_log_entry= next_log_entry;
954
 
  else
955
 
    global_ddl_log.first_used= next_log_entry;
956
 
  if (next_log_entry)
957
 
    next_log_entry->prev_log_entry= prev_log_entry;
958
 
  return;
959
 
}
960
 
 
961
 
 
962
 
/*
963
 
  Execute one entry in the ddl log. Executing an entry means executing
964
 
  a linked list of actions.
965
 
  SYNOPSIS
966
 
    execute_ddl_log_entry()
967
 
    first_entry                Reference to first action in entry
968
 
  RETURN VALUES
969
 
    true                       Error
970
 
    false                      Success
971
 
*/
972
 
 
973
 
bool execute_ddl_log_entry(THD *thd, uint first_entry)
974
 
{
975
 
  DDL_LOG_ENTRY ddl_log_entry;
976
 
  uint read_entry= first_entry;
977
 
 
978
 
  pthread_mutex_lock(&LOCK_gdl);
979
 
  do
980
 
  {
981
 
    if (read_ddl_log_entry(read_entry, &ddl_log_entry))
982
 
    {
983
 
      /* Write to error log and continue with next log entry */
984
 
      sql_print_error("Failed to read entry = %u from ddl log",
985
 
                      read_entry);
986
 
      break;
987
 
    }
988
 
    assert(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
989
 
                ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
990
 
 
991
 
    if (execute_ddl_log_action(thd, &ddl_log_entry))
992
 
    {
993
 
      /* Write to error log and continue with next log entry */
994
 
      sql_print_error("Failed to execute action for entry = %u from ddl log",
995
 
                      read_entry);
996
 
      break;
997
 
    }
998
 
    read_entry= ddl_log_entry.next_entry;
999
 
  } while (read_entry);
1000
 
  pthread_mutex_unlock(&LOCK_gdl);
1001
 
  return(false);
1002
 
}
1003
 
 
1004
 
 
1005
 
/*
1006
 
  Close the ddl log
1007
 
  SYNOPSIS
1008
 
    close_ddl_log()
1009
 
  RETURN VALUES
1010
 
    NONE
1011
 
*/
1012
 
 
1013
 
static void close_ddl_log()
1014
 
{
1015
 
  if (global_ddl_log.file_id >= 0)
1016
 
  {
1017
 
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
1018
 
    global_ddl_log.file_id= (File) -1;
1019
 
  }
1020
 
  return;
1021
 
}
1022
 
 
1023
 
 
1024
 
/*
1025
 
  Execute the ddl log at recovery of MySQL Server
1026
 
  SYNOPSIS
1027
 
    execute_ddl_log_recovery()
1028
 
  RETURN VALUES
1029
 
    NONE
1030
 
*/
1031
 
 
1032
 
void execute_ddl_log_recovery()
1033
 
{
1034
 
  uint num_entries, i;
1035
 
  THD *thd;
1036
 
  DDL_LOG_ENTRY ddl_log_entry;
1037
 
  char file_name[FN_REFLEN];
1038
 
 
1039
 
  /*
1040
 
    Initialise global_ddl_log struct
1041
 
  */
1042
 
  bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
1043
 
  global_ddl_log.inited= false;
1044
 
  global_ddl_log.recovery_phase= true;
1045
 
  global_ddl_log.io_size= IO_SIZE;
1046
 
  global_ddl_log.file_id= (File) -1;
1047
 
 
1048
 
  /*
1049
 
    To be able to run this from boot, we allocate a temporary THD
1050
 
  */
1051
 
  if (!(thd=new THD))
1052
 
    return;
1053
 
  thd->thread_stack= (char*) &thd;
1054
 
  thd->store_globals();
1055
 
 
1056
 
  num_entries= read_ddl_log_header();
1057
 
  for (i= 1; i < num_entries + 1; i++)
1058
 
  {
1059
 
    if (read_ddl_log_entry(i, &ddl_log_entry))
1060
 
    {
1061
 
      sql_print_error("Failed to read entry no = %u from ddl log",
1062
 
                       i);
1063
 
      continue;
1064
 
    }
1065
 
    if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
1066
 
    {
1067
 
      if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
1068
 
      {
1069
 
        /* Real unpleasant scenario but we continue anyways.  */
1070
 
        continue;
1071
 
      }
1072
 
    }
1073
 
  }
1074
 
  close_ddl_log();
1075
 
  create_ddl_log_file_name(file_name);
1076
 
  VOID(my_delete(file_name, MYF(0)));
1077
 
  global_ddl_log.recovery_phase= false;
1078
 
  delete thd;
1079
 
  /* Remember that we don't have a THD */
1080
 
  my_pthread_setspecific_ptr(THR_THD,  0);
1081
 
  return;
1082
 
}
1083
 
 
1084
 
 
1085
 
/*
1086
 
  Release all memory allocated to the ddl log
1087
 
  SYNOPSIS
1088
 
    release_ddl_log()
1089
 
  RETURN VALUES
1090
 
    NONE
1091
 
*/
1092
 
 
1093
 
void release_ddl_log()
1094
 
{
1095
 
  DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
1096
 
  DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
1097
 
 
1098
 
  if (!global_ddl_log.do_release)
1099
 
    return;
1100
 
 
1101
 
  pthread_mutex_lock(&LOCK_gdl);
1102
 
  while (used_list)
1103
 
  {
1104
 
    DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
1105
 
    my_free(used_list, MYF(0));
1106
 
    used_list= tmp;
1107
 
  }
1108
 
  while (free_list)
1109
 
  {
1110
 
    DDL_LOG_MEMORY_ENTRY *tmp= free_list->next_log_entry;
1111
 
    my_free(free_list, MYF(0));
1112
 
    free_list= tmp;
1113
 
  }
1114
 
  close_ddl_log();
1115
 
  global_ddl_log.inited= 0;
1116
 
  pthread_mutex_unlock(&LOCK_gdl);
1117
 
  VOID(pthread_mutex_destroy(&LOCK_gdl));
1118
 
  global_ddl_log.do_release= false;
1119
 
  return;
1120
 
}
1121
 
 
1122
 
 
1123
 
/*
1124
 
---------------------------------------------------------------------------
1125
 
 
1126
 
  END MODULE DDL log
1127
 
  --------------------
1128
 
 
1129
 
---------------------------------------------------------------------------
1130
 
*/
1131
 
 
1132
 
 
1133
 
/*
1134
224
  SYNOPSIS
1135
225
    write_bin_log()
1136
226
    thd                           Thread object
1183
273
 
1184
274
*/
1185
275
 
1186
 
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
1187
 
                    my_bool drop_temporary)
 
276
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
1188
277
{
1189
278
  bool error, need_start_waiting= false;
1190
279
 
1249
338
   -1   Thread was killed
1250
339
*/
1251
340
 
1252
 
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
 
341
int mysql_rm_table_part2(THD *thd, TableList *tables, bool if_exists,
1253
342
                         bool drop_temporary, bool drop_view,
1254
343
                         bool dont_log_query)
1255
344
{
1256
 
  TABLE_LIST *table;
 
345
  TableList *table;
1257
346
  char path[FN_REFLEN], *alias;
1258
 
  uint path_length;
 
347
  uint32_t path_length;
1259
348
  String wrong_tables;
1260
349
  int error= 0;
1261
350
  int non_temp_tables_count= 0;
1266
355
  {
1267
356
    built_query.set_charset(system_charset_info);
1268
357
    if (if_exists)
1269
 
      built_query.append("DROP TABLE IF EXISTS ");
 
358
      built_query.append("DROP Table IF EXISTS ");
1270
359
    else
1271
 
      built_query.append("DROP TABLE ");
 
360
      built_query.append("DROP Table ");
1272
361
  }
1273
362
 
1274
363
  mysql_ha_rm_tables(thd, tables, false);
1348
437
    table_type= table->db_type;
1349
438
    if (!drop_temporary)
1350
439
    {
1351
 
      TABLE *locked_table;
 
440
      Table *locked_table;
1352
441
      abort_locked_tables(thd, db, table->table_name);
1353
442
      remove_table_from_cache(thd, db, table->table_name,
1354
443
                              RTFC_WAIT_OTHER_THREAD_FLAG |
1373
462
    }
1374
463
    if (drop_temporary ||
1375
464
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
1376
 
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
 
465
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != true)))
1377
466
    {
1378
467
      // Table was not found on disk and table can't be created from engine
1379
468
      if (if_exists)
1380
 
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
469
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1381
470
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
1382
471
                            table->table_name);
1383
472
      else
1410
499
      {
1411
500
        int new_error;
1412
501
        /* Delete the table definition file */
1413
 
        strmov(end,reg_ext);
 
502
        my_stpcpy(end,reg_ext);
1414
503
        if (!(new_error=my_delete(path,MYF(MY_WME))))
1415
504
        {
1416
505
          some_tables_deleted=1;
1439
528
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
1440
529
                      wrong_tables.c_ptr());
1441
530
    else
 
531
    {
1442
532
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
 
533
    }
1443
534
    error= 1;
1444
535
  }
1445
536
 
1491
582
  }
1492
583
  pthread_mutex_lock(&LOCK_open);
1493
584
err_with_placeholders:
1494
 
  unlock_table_names(thd, tables, (TABLE_LIST*) 0);
 
585
  unlock_table_names(thd, tables, (TableList*) 0);
1495
586
  pthread_mutex_unlock(&LOCK_open);
1496
587
  thd->no_warnings_for_error= 0;
1497
588
  return(error);
1514
605
*/
1515
606
 
1516
607
bool quick_rm_table(handlerton *base,const char *db,
1517
 
                    const char *table_name, uint flags)
 
608
                    const char *table_name, uint32_t flags)
1518
609
{
1519
610
  char path[FN_REFLEN];
1520
611
  bool error= 0;
1521
612
 
1522
 
  uint path_length= build_table_filename(path, sizeof(path),
 
613
  uint32_t path_length= build_table_filename(path, sizeof(path),
1523
614
                                         db, table_name, reg_ext, flags);
1524
615
  if (my_delete(path,MYF(0)))
1525
616
    error= 1; /* purecov: inspected */
1595
686
 
1596
687
bool check_duplicates_in_interval(const char *set_or_name,
1597
688
                                  const char *name, TYPELIB *typelib,
1598
 
                                  CHARSET_INFO *cs, unsigned int *dup_val_count)
 
689
                                  const CHARSET_INFO * const cs, unsigned int *dup_val_count)
1599
690
{
1600
691
  TYPELIB tmp= *typelib;
1601
692
  const char **cur_value= typelib->type_names;
1636
727
  RETURN VALUES
1637
728
    void
1638
729
*/
1639
 
void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
1640
 
                                uint32 *max_length, uint32 *tot_length)
 
730
void calculate_interval_lengths(const CHARSET_INFO * const cs, TYPELIB *interval,
 
731
                                uint32_t *max_length, uint32_t *tot_length)
1641
732
{
1642
733
  const char **pos;
1643
 
  uint *len;
 
734
  uint32_t *len;
1644
735
  *max_length= *tot_length= 0;
1645
736
  for (pos= interval->type_names, len= interval->type_lengths;
1646
737
       *pos ; pos++, len++)
1647
738
  {
1648
 
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
 
739
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
1649
740
    *tot_length+= length;
1650
 
    set_if_bigger(*max_length, (uint32)length);
 
741
    set_if_bigger(*max_length, (uint32_t)length);
1651
742
  }
1652
743
}
1653
744
 
1672
763
*/
1673
764
 
1674
765
int prepare_create_field(Create_field *sql_field, 
1675
 
                         uint *blob_columns,
 
766
                         uint32_t *blob_columns,
1676
767
                         int *timestamps, int *timestamps_with_niladic,
1677
 
                         int64_t table_flags __attribute__((__unused__)))
 
768
                         int64_t table_flags __attribute__((unused)))
1678
769
{
1679
770
  unsigned int dup_val_count;
1680
771
 
1685
776
  assert(sql_field->charset);
1686
777
 
1687
778
  switch (sql_field->sql_type) {
1688
 
  case MYSQL_TYPE_BLOB:
 
779
  case DRIZZLE_TYPE_BLOB:
1689
780
    sql_field->pack_flag=FIELDFLAG_BLOB |
1690
781
      pack_length_to_packflag(sql_field->pack_length -
1691
782
                              portable_sizeof_char_ptr);
1695
786
    sql_field->unireg_check=Field::BLOB_FIELD;
1696
787
    (*blob_columns)++;
1697
788
    break;
1698
 
  case MYSQL_TYPE_VARCHAR:
1699
 
  case MYSQL_TYPE_STRING:
 
789
  case DRIZZLE_TYPE_VARCHAR:
1700
790
    sql_field->pack_flag=0;
1701
791
    if (sql_field->charset->state & MY_CS_BINSORT)
1702
792
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1703
793
    break;
1704
 
  case MYSQL_TYPE_ENUM:
 
794
  case DRIZZLE_TYPE_ENUM:
1705
795
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
1706
796
      FIELDFLAG_INTERVAL;
1707
797
    if (sql_field->charset->state & MY_CS_BINSORT)
1712
802
                                     sql_field->charset, &dup_val_count))
1713
803
      return(1);
1714
804
    break;
1715
 
  case MYSQL_TYPE_SET:
1716
 
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
1717
 
      FIELDFLAG_BITFIELD;
1718
 
    if (sql_field->charset->state & MY_CS_BINSORT)
1719
 
      sql_field->pack_flag|=FIELDFLAG_BINARY;
1720
 
    sql_field->unireg_check=Field::BIT_FIELD;
1721
 
    if (check_duplicates_in_interval("SET",sql_field->field_name,
1722
 
                                 sql_field->interval,
1723
 
                                     sql_field->charset, &dup_val_count))
1724
 
      return(1);
1725
 
    /* Check that count of unique members is not more then 64 */
1726
 
    if (sql_field->interval->count -  dup_val_count > sizeof(int64_t)*8)
1727
 
    {
1728
 
       my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
1729
 
       return(1);
1730
 
    }
1731
 
    break;
1732
 
  case MYSQL_TYPE_NEWDATE:  // Rest of string types
1733
 
  case MYSQL_TYPE_TIME:
1734
 
  case MYSQL_TYPE_DATETIME:
1735
 
  case MYSQL_TYPE_NULL:
 
805
  case DRIZZLE_TYPE_NEWDATE:  // Rest of string types
 
806
  case DRIZZLE_TYPE_TIME:
 
807
  case DRIZZLE_TYPE_DATETIME:
 
808
  case DRIZZLE_TYPE_NULL:
1736
809
    sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
1737
810
    break;
1738
 
  case MYSQL_TYPE_NEWDECIMAL:
 
811
  case DRIZZLE_TYPE_NEWDECIMAL:
1739
812
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
1740
813
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
1741
814
                           FIELDFLAG_DECIMAL) |
1742
 
                          (sql_field->flags & ZEROFILL_FLAG ?
1743
 
                           FIELDFLAG_ZEROFILL : 0) |
 
815
                          (sql_field->flags & DECIMAL_FLAG ?  FIELDFLAG_DECIMAL_POSITION : 0) |
1744
816
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
1745
817
    break;
1746
 
  case MYSQL_TYPE_TIMESTAMP:
 
818
  case DRIZZLE_TYPE_TIMESTAMP:
1747
819
    /* We should replace old TIMESTAMP fields with their newer analogs */
1748
820
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
1749
821
    {
1764
836
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
1765
837
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
1766
838
                           FIELDFLAG_DECIMAL) |
1767
 
                          (sql_field->flags & ZEROFILL_FLAG ?
1768
 
                           FIELDFLAG_ZEROFILL : 0) |
1769
839
                          f_settype((uint) sql_field->sql_type) |
1770
840
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
1771
841
    break;
1807
877
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
1808
878
                           Alter_info *alter_info,
1809
879
                           bool tmp_table,
1810
 
                               uint *db_options,
 
880
                               uint32_t *db_options,
1811
881
                               handler *file, KEY **key_info_buffer,
1812
 
                               uint *key_count, int select_field_count)
 
882
                               uint32_t *key_count, int select_field_count)
1813
883
{
1814
884
  const char    *key_name;
1815
885
  Create_field  *sql_field,*dup_field;
1822
892
  int           select_field_pos,auto_increment=0;
1823
893
  List_iterator<Create_field> it(alter_info->create_list);
1824
894
  List_iterator<Create_field> it2(alter_info->create_list);
1825
 
  uint total_uneven_bit_length= 0;
 
895
  uint32_t total_uneven_bit_length= 0;
1826
896
 
1827
897
  select_field_pos= alter_info->create_list.elements - select_field_count;
1828
898
  null_fields=blob_columns=0;
1831
901
 
1832
902
  for (field_no=0; (sql_field=it++) ; field_no++)
1833
903
  {
1834
 
    CHARSET_INFO *save_cs;
 
904
    const CHARSET_INFO *save_cs;
1835
905
 
1836
906
    /*
1837
907
      Initialize length from its original value (number of characters),
1842
912
    if (!sql_field->charset)
1843
913
      sql_field->charset= create_info->default_table_charset;
1844
914
    /*
1845
 
      table_charset is set in ALTER TABLE if we want change character set
 
915
      table_charset is set in ALTER Table if we want change character set
1846
916
      for all varchar/char columns.
1847
917
      But the table charset must not affect the BLOB fields, so don't
1848
918
      allow to change my_charset_bin to somethig else.
1868
938
    */
1869
939
    if (sql_field->def && 
1870
940
        save_cs != sql_field->def->collation.collation &&
1871
 
        (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
1872
 
         sql_field->sql_type == MYSQL_TYPE_STRING ||
1873
 
         sql_field->sql_type == MYSQL_TYPE_SET ||
1874
 
         sql_field->sql_type == MYSQL_TYPE_ENUM))
 
941
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
1875
942
    {
1876
943
      /*
1877
944
        Starting from 5.1 we work here with a copy of Create_field
1893
960
      }
1894
961
    }
1895
962
 
1896
 
    if (sql_field->sql_type == MYSQL_TYPE_SET ||
1897
 
        sql_field->sql_type == MYSQL_TYPE_ENUM)
 
963
    if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
1898
964
    {
1899
 
      uint32 dummy;
1900
 
      CHARSET_INFO *cs= sql_field->charset;
 
965
      uint32_t dummy;
 
966
      const CHARSET_INFO * const cs= sql_field->charset;
1901
967
      TYPELIB *interval= sql_field->interval;
1902
968
 
1903
969
      /*
1917
983
        List_iterator<String> int_it(sql_field->interval_list);
1918
984
        String conv, *tmp;
1919
985
        char comma_buf[4];
1920
 
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
1921
 
                                          (uchar*) comma_buf + 
 
986
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
 
987
                                          (unsigned char*) comma_buf + 
1922
988
                                          sizeof(comma_buf));
1923
989
        assert(comma_length > 0);
1924
 
        for (uint i= 0; (tmp= int_it++); i++)
 
990
        for (uint32_t i= 0; (tmp= int_it++); i++)
1925
991
        {
1926
 
          uint lengthsp;
 
992
          uint32_t lengthsp;
1927
993
          if (String::needs_conversion(tmp->length(), tmp->charset(),
1928
994
                                       cs, &dummy))
1929
995
          {
1930
 
            uint cnv_errs;
 
996
            uint32_t cnv_errs;
1931
997
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
1932
998
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
1933
999
                                                  conv.length());
1938
1004
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
1939
1005
                                       interval->type_lengths[i]);
1940
1006
          interval->type_lengths[i]= lengthsp;
1941
 
          ((uchar *)interval->type_names[i])[lengthsp]= '\0';
1942
 
          if (sql_field->sql_type == MYSQL_TYPE_SET)
1943
 
          {
1944
 
            if (cs->coll->instr(cs, interval->type_names[i], 
1945
 
                                interval->type_lengths[i], 
1946
 
                                comma_buf, comma_length, NULL, 0))
1947
 
            {
1948
 
              my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
1949
 
              return(true);
1950
 
            }
1951
 
          }
 
1007
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
1952
1008
        }
1953
1009
        sql_field->interval_list.empty(); // Don't need interval_list anymore
1954
1010
      }
1955
1011
 
1956
 
      if (sql_field->sql_type == MYSQL_TYPE_SET)
1957
 
      {
1958
 
        uint32 field_length;
1959
 
        if (sql_field->def != NULL)
1960
 
        {
1961
 
          char *not_used;
1962
 
          uint not_used2;
1963
 
          bool not_found= 0;
1964
 
          String str, *def= sql_field->def->val_str(&str);
1965
 
          if (def == NULL) /* SQL "NULL" maps to NULL */
1966
 
          {
1967
 
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
1968
 
            {
1969
 
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1970
 
              return(true);
1971
 
            }
1972
 
 
1973
 
            /* else, NULL is an allowed value */
1974
 
            (void) find_set(interval, NULL, 0,
1975
 
                            cs, &not_used, &not_used2, &not_found);
1976
 
          }
1977
 
          else /* not NULL */
1978
 
          {
1979
 
            (void) find_set(interval, def->ptr(), def->length(),
1980
 
                            cs, &not_used, &not_used2, &not_found);
1981
 
          }
1982
 
 
1983
 
          if (not_found)
1984
 
          {
1985
 
            my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
1986
 
            return(true);
1987
 
          }
1988
 
        }
1989
 
        calculate_interval_lengths(cs, interval, &dummy, &field_length);
1990
 
        sql_field->length= field_length + (interval->count - 1);
1991
 
      }
1992
 
      else  /* MYSQL_TYPE_ENUM */
1993
 
      {
1994
 
        uint32 field_length;
1995
 
        assert(sql_field->sql_type == MYSQL_TYPE_ENUM);
 
1012
      /* DRIZZLE_TYPE_ENUM */
 
1013
      {
 
1014
        uint32_t field_length;
 
1015
        assert(sql_field->sql_type == DRIZZLE_TYPE_ENUM);
1996
1016
        if (sql_field->def != NULL)
1997
1017
        {
1998
1018
          String str, *def= sql_field->def->val_str(&str);
2082
1102
    }
2083
1103
    /* Don't pack rows in old tables if the user has requested this */
2084
1104
    if ((sql_field->flags & BLOB_FLAG) ||
2085
 
        (sql_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
1105
        (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
2086
1106
      (*db_options)|= HA_OPTION_PACK_RECORD;
2087
1107
    it2.rewind();
2088
1108
  }
2100
1120
                             &timestamps, &timestamps_with_niladic,
2101
1121
                             file->ha_table_flags()))
2102
1122
      return(true);
2103
 
    if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
 
1123
    if (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
2104
1124
      create_info->varchar= true;
2105
1125
    sql_field->offset= record_offset;
2106
1126
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
2137
1157
 
2138
1158
  List_iterator<Key> key_iterator(alter_info->key_list);
2139
1159
  List_iterator<Key> key_iterator2(alter_info->key_list);
2140
 
  uint key_parts=0, fk_key_count=0;
 
1160
  uint32_t key_parts=0, fk_key_count=0;
2141
1161
  bool primary_key=0,unique_key=0;
2142
1162
  Key *key, *key2;
2143
 
  uint tmp, key_number;
 
1163
  uint32_t tmp, key_number;
2144
1164
  /* special marker for keys to be ignored */
2145
1165
  static char ignore_key[1];
2146
1166
 
2230
1250
  key_number=0;
2231
1251
  for (; (key=key_iterator++) ; key_number++)
2232
1252
  {
2233
 
    uint key_length=0;
 
1253
    uint32_t key_length=0;
2234
1254
    Key_part_spec *column;
2235
1255
 
2236
1256
    if (key->name.str == ignore_key)
2257
1277
    if (key->generated)
2258
1278
      key_info->flags|= HA_GENERATED_KEY;
2259
1279
 
2260
 
    key_info->key_parts=(uint8) key->columns.elements;
 
1280
    key_info->key_parts=(uint8_t) key->columns.elements;
2261
1281
    key_info->key_part=key_part_info;
2262
1282
    key_info->usable_key_parts= key_number;
2263
1283
    key_info->algorithm= key->key_create_info.algorithm;
2274
1294
    if (key_info->block_size)
2275
1295
      key_info->flags|= HA_USES_BLOCK_SIZE;
2276
1296
 
2277
 
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
1297
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
2278
1298
                                           key->key_create_info.comment.str,
2279
1299
                                           key->key_create_info.comment.str +
2280
1300
                                           key->key_create_info.comment.length,
2296
1316
    }
2297
1317
 
2298
1318
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
2299
 
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
 
1319
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
2300
1320
    {
2301
 
      uint length;
 
1321
      uint32_t length;
2302
1322
      Key_part_spec *dup_column;
2303
1323
 
2304
1324
      it.rewind();
2368
1388
      }
2369
1389
 
2370
1390
      key_part_info->fieldnr= field;
2371
 
      key_part_info->offset=  (uint16) sql_field->offset;
 
1391
      key_part_info->offset=  (uint16_t) sql_field->offset;
2372
1392
      key_part_info->key_type=sql_field->pack_flag;
2373
1393
      length= sql_field->key_length;
2374
1394
 
2379
1399
          if ((length=column->length) > max_key_length ||
2380
1400
              length > file->max_key_part_length())
2381
1401
          {
2382
 
            length=min(max_key_length, file->max_key_part_length());
 
1402
            length=cmin(max_key_length, file->max_key_part_length());
2383
1403
            if (key->type == Key::MULTIPLE)
2384
1404
            {
2385
1405
              /* not a critical problem */
2386
 
              char warn_buff[MYSQL_ERRMSG_SIZE];
 
1406
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
2387
1407
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
2388
1408
                       length);
2389
 
              push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1409
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2390
1410
                           ER_TOO_LONG_KEY, warn_buff);
2391
1411
              /* Align key length to multibyte char boundary */
2392
1412
              length-= length % sql_field->charset->mbmaxlen;
2422
1442
        if (key->type == Key::MULTIPLE)
2423
1443
        {
2424
1444
          /* not a critical problem */
2425
 
          char warn_buff[MYSQL_ERRMSG_SIZE];
 
1445
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
2426
1446
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
2427
1447
                   length);
2428
 
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
1448
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2429
1449
                       ER_TOO_LONG_KEY, warn_buff);
2430
1450
          /* Align key length to multibyte char boundary */
2431
1451
          length-= length % sql_field->charset->mbmaxlen;
2436
1456
          return(true);
2437
1457
        }
2438
1458
      }
2439
 
      key_part_info->length=(uint16) length;
 
1459
      key_part_info->length=(uint16_t) length;
2440
1460
      /* Use packed keys for long strings on the first column */
2441
1461
      if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
2442
1462
          (length >= KEY_DEFAULT_PACK_LENGTH &&
2443
 
           (sql_field->sql_type == MYSQL_TYPE_STRING ||
2444
 
            sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
 
1463
           (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
2445
1464
            sql_field->pack_flag & FIELDFLAG_BLOB)))
2446
1465
      {
2447
1466
        if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
2448
 
            sql_field->sql_type == MYSQL_TYPE_VARCHAR)
 
1467
            sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
2449
1468
          key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
2450
1469
        else
2451
1470
          key_info->flags|= HA_PACK_KEY;
2489
1508
    }
2490
1509
    if (!(key_info->flags & HA_NULL_PART_KEY))
2491
1510
      unique_key=1;
2492
 
    key_info->key_length=(uint16) key_length;
 
1511
    key_info->key_length=(uint16_t) key_length;
2493
1512
    if (key_length > max_key_length)
2494
1513
    {
2495
1514
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
2509
1528
    return(true);
2510
1529
  }
2511
1530
  /* Sort keys in optimized order */
2512
 
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
 
1531
  my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
2513
1532
           (qsort_cmp) sort_keys);
2514
1533
  create_info->null_bits= null_fields;
2515
1534
 
2521
1540
 
2522
1541
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
2523
1542
        !sql_field->def &&
2524
 
        sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
 
1543
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
2525
1544
        (sql_field->flags & NOT_NULL_FLAG) &&
2526
1545
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
2527
1546
    {
2593
1612
        In this case the error is given
2594
1613
*/
2595
1614
 
2596
 
static bool prepare_blob_field(THD *thd __attribute__((__unused__)),
 
1615
static bool prepare_blob_field(THD *thd __attribute__((unused)),
2597
1616
                               Create_field *sql_field)
2598
1617
{
2599
1618
 
2607
1626
    
2608
1627
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
2609
1628
  {
2610
 
    if (sql_field->sql_type == MYSQL_TYPE_BLOB)
 
1629
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
2611
1630
    {
2612
1631
      /* The user has given a length to the blob column */
2613
1632
      sql_field->sql_type= get_blob_type_from_length(sql_field->length);
2636
1655
 
2637
1656
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
2638
1657
{
2639
 
  if (sql_field->sql_type == MYSQL_TYPE_SET ||
2640
 
      sql_field->sql_type == MYSQL_TYPE_ENUM)
 
1658
  if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
2641
1659
  {
2642
 
    uint32 field_length, dummy;
2643
 
    if (sql_field->sql_type == MYSQL_TYPE_SET)
2644
 
    {
2645
 
      calculate_interval_lengths(sql_field->charset,
2646
 
                                 sql_field->interval, &dummy, 
2647
 
                                 &field_length);
2648
 
      sql_field->length= field_length + 
2649
 
                         (sql_field->interval->count - 1);
2650
 
    }
2651
 
    else /* MYSQL_TYPE_ENUM */
 
1660
    uint32_t field_length, dummy;
 
1661
    /* DRIZZLE_TYPE_ENUM */
2652
1662
    {
2653
1663
      calculate_interval_lengths(sql_field->charset,
2654
1664
                                 sql_field->interval,
2677
1687
    fields              List of fields to create
2678
1688
    keys                List of keys to create
2679
1689
    internal_tmp_table  Set to 1 if this is an internal temporary table
2680
 
                        (From ALTER TABLE)
 
1690
                        (From ALTER Table)
2681
1691
    select_field_count  
2682
1692
 
2683
1693
  DESCRIPTION
2703
1713
                                HA_CREATE_INFO *create_info,
2704
1714
                                Alter_info *alter_info,
2705
1715
                                bool internal_tmp_table,
2706
 
                                uint select_field_count)
 
1716
                                uint32_t select_field_count)
2707
1717
{
2708
1718
  char          path[FN_REFLEN];
2709
 
  uint          path_length;
 
1719
  uint32_t          path_length;
2710
1720
  const char    *alias;
2711
1721
  uint          db_options, key_count;
2712
1722
  KEY           *key_info_buffer;
2768
1778
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
2769
1779
    {
2770
1780
      create_info->table_existed= 1;            // Mark that table existed
2771
 
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
1781
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2772
1782
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
2773
1783
                          alias);
2774
1784
      error= 0;
2778
1788
    goto err;
2779
1789
  }
2780
1790
 
2781
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
1791
  pthread_mutex_lock(&LOCK_open);
2782
1792
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
2783
1793
  {
2784
1794
    if (!access(path,F_OK))
2854
1864
#endif /* HAVE_READLINK */
2855
1865
  {
2856
1866
    if (create_info->data_file_name)
2857
 
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
 
1867
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
2858
1868
                   "DATA DIRECTORY option ignored");
2859
1869
    if (create_info->index_file_name)
2860
 
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
 
1870
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
2861
1871
                   "INDEX DIRECTORY option ignored");
2862
1872
    create_info->data_file_name= create_info->index_file_name= 0;
2863
1873
  }
2894
1904
    write_bin_log(thd, true, thd->query, thd->query_length);
2895
1905
  error= false;
2896
1906
unlock_and_end:
2897
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
1907
  pthread_mutex_unlock(&LOCK_open);
2898
1908
 
2899
1909
err:
2900
1910
  thd_proc_info(thd, "After create");
2903
1913
 
2904
1914
warn:
2905
1915
  error= false;
2906
 
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
1916
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2907
1917
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
2908
1918
                      alias);
2909
1919
  create_info->table_existed= 1;                // Mark that table existed
2919
1929
                        HA_CREATE_INFO *create_info,
2920
1930
                        Alter_info *alter_info,
2921
1931
                        bool internal_tmp_table,
2922
 
                        uint select_field_count)
 
1932
                        uint32_t select_field_count)
2923
1933
{
2924
 
  TABLE *name_lock= 0;
 
1934
  Table *name_lock= 0;
2925
1935
  bool result;
2926
1936
 
2927
1937
  /* Wait for any database locks */
2928
1938
  pthread_mutex_lock(&LOCK_lock_db);
2929
1939
  while (!thd->killed &&
2930
 
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
 
1940
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
2931
1941
  {
2932
1942
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
2933
1943
    pthread_mutex_lock(&LOCK_lock_db);
2952
1962
    {
2953
1963
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
2954
1964
      {
2955
 
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
1965
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2956
1966
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
2957
1967
                            table_name);
2958
1968
        create_info->table_existed= 1;
3015
2025
    Only 3 chars + '\0' left, so need to limit to 2 digit
3016
2026
    This is ok as we can't have more than 100 keys anyway
3017
2027
  */
3018
 
  for (uint i=2 ; i< 100; i++)
 
2028
  for (uint32_t i=2 ; i< 100; i++)
3019
2029
  {
3020
2030
    *buff_end= '_';
3021
2031
    int10_to_str(i, buff_end+1, 10);
3055
2065
bool
3056
2066
mysql_rename_table(handlerton *base, const char *old_db,
3057
2067
                   const char *old_name, const char *new_db,
3058
 
                   const char *new_name, uint flags)
 
2068
                   const char *new_name, uint32_t flags)
3059
2069
{
3060
2070
  THD *thd= current_thd;
3061
2071
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
3080
2090
  if (lower_case_table_names == 2 && file &&
3081
2091
      !(file->ha_table_flags() & HA_FILE_BASED))
3082
2092
  {
3083
 
    strmov(tmp_name, old_name);
 
2093
    my_stpcpy(tmp_name, old_name);
3084
2094
    my_casedn_str(files_charset_info, tmp_name);
3085
2095
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
3086
2096
                         flags & FN_FROM_IS_TMP);
3087
2097
    from_base= lc_from;
3088
2098
 
3089
 
    strmov(tmp_name, new_name);
 
2099
    my_stpcpy(tmp_name, new_name);
3090
2100
    my_casedn_str(files_charset_info, tmp_name);
3091
2101
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
3092
2102
                         flags & FN_TO_IS_TMP);
3104
2114
  }
3105
2115
  delete file;
3106
2116
  if (error == HA_ERR_WRONG_COMMAND)
3107
 
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
 
2117
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
3108
2118
  else if (error)
3109
2119
    my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
3110
2120
  return(error != 0);
3130
2140
    Win32 clients must also have a WRITE LOCK on the table !
3131
2141
*/
3132
2142
 
3133
 
void wait_while_table_is_used(THD *thd, TABLE *table,
 
2143
void wait_while_table_is_used(THD *thd, Table *table,
3134
2144
                              enum ha_extra_function function)
3135
2145
{
3136
2146
 
3137
2147
  safe_mutex_assert_owner(&LOCK_open);
3138
2148
 
3139
 
  VOID(table->file->extra(function));
 
2149
  table->file->extra(function);
3140
2150
  /* Mark all tables that are in use as 'old' */
3141
2151
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
3142
2152
 
3164
2174
    Win32 clients must also have a WRITE LOCK on the table !
3165
2175
*/
3166
2176
 
3167
 
void close_cached_table(THD *thd, TABLE *table)
 
2177
void close_cached_table(THD *thd, Table *table)
3168
2178
{
3169
2179
 
3170
2180
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3182
2192
  return;
3183
2193
}
3184
2194
 
3185
 
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
 
2195
static int send_check_errmsg(THD *thd, TableList* table,
3186
2196
                             const char* operator_name, const char* errmsg)
3187
2197
 
3188
2198
{
3199
2209
}
3200
2210
 
3201
2211
 
3202
 
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
 
2212
static int prepare_for_repair(THD *thd, TableList *table_list,
3203
2213
                              HA_CHECK_OPT *check_opt)
3204
2214
{
3205
2215
  int error= 0;
3206
 
  TABLE tmp_table, *table;
 
2216
  Table tmp_table, *table;
3207
2217
  TABLE_SHARE *share;
3208
2218
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
3209
2219
  const char **ext;
3215
2225
  if (!(table= table_list->table))              /* if open_ltable failed */
3216
2226
  {
3217
2227
    char key[MAX_DBKEY_LENGTH];
3218
 
    uint key_length;
 
2228
    uint32_t key_length;
3219
2229
 
3220
2230
    key_length= create_table_def_key(thd, key, table_list, 0);
3221
2231
    pthread_mutex_lock(&LOCK_open);
3237
2247
  }
3238
2248
 
3239
2249
  /*
3240
 
    REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
 
2250
    REPAIR Table ... USE_FRM for temporary tables makes little sense.
3241
2251
  */
3242
2252
  if (table->s->tmp_table)
3243
2253
  {
3267
2277
    goto end;                                   // No data file
3268
2278
 
3269
2279
  // Name of data file
3270
 
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
 
2280
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
3271
2281
  if (stat(from, &stat_info))
3272
2282
    goto end;                           // Can't use USE_FRM flag
3273
2283
 
3347
2357
    true  Message should be sent by caller 
3348
2358
          (admin operation or network communication failed)
3349
2359
*/
3350
 
static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
 
2360
static bool mysql_admin_table(THD* thd, TableList* tables,
3351
2361
                              HA_CHECK_OPT* check_opt,
3352
2362
                              const char *operator_name,
3353
2363
                              thr_lock_type lock_type,
3354
2364
                              bool open_for_modify,
3355
2365
                              bool no_warnings_for_error,
3356
 
                              uint extra_open_options,
3357
 
                              int (*prepare_func)(THD *, TABLE_LIST *,
 
2366
                              uint32_t extra_open_options,
 
2367
                              int (*prepare_func)(THD *, TableList *,
3358
2368
                                                  HA_CHECK_OPT *),
3359
2369
                              int (handler::*operator_func)(THD *,
3360
2370
                                                            HA_CHECK_OPT *))
3361
2371
{
3362
 
  TABLE_LIST *table;
 
2372
  TableList *table;
3363
2373
  SELECT_LEX *select= &thd->lex->select_lex;
3364
2374
  List<Item> field_list;
3365
2375
  Item *item;
3366
2376
  Protocol *protocol= thd->protocol;
3367
2377
  LEX *lex= thd->lex;
3368
2378
  int result_code= 0;
3369
 
  CHARSET_INFO *cs= system_charset_info;
 
2379
  const CHARSET_INFO * const cs= system_charset_info;
3370
2380
 
3371
2381
  if (end_active_trans(thd))
3372
2382
    return(1);
3392
2402
    char* db = table->db;
3393
2403
    bool fatal_error=0;
3394
2404
 
3395
 
    strxmov(table_name, db, ".", table->table_name, NullS);
 
2405
    strxmov(table_name, db, ".", table->table_name, NULL);
3396
2406
    thd->open_options|= extra_open_options;
3397
2407
    table->lock_type= lock_type;
3398
2408
    /* open only one table from local list of command */
3399
2409
    {
3400
 
      TABLE_LIST *save_next_global, *save_next_local;
 
2410
      TableList *save_next_global, *save_next_local;
3401
2411
      save_next_global= table->next_global;
3402
2412
      table->next_global= 0;
3403
2413
      save_next_local= table->next_local;
3404
2414
      table->next_local= 0;
3405
 
      select->table_list.first= (uchar*)table;
 
2415
      select->table_list.first= (unsigned char*)table;
3406
2416
      /*
3407
2417
        Time zone tables and SP tables can be add to lex->query_tables list,
3408
2418
        so it have to be prepared.
3413
2423
      lex->query_tables_last= &table->next_global;
3414
2424
      lex->query_tables_own_last= 0;
3415
2425
      thd->no_warnings_for_error= no_warnings_for_error;
3416
 
      table->required_type=FRMTYPE_TABLE;
3417
2426
 
3418
2427
      open_and_lock_tables(thd, table);
3419
2428
      thd->no_warnings_for_error= 0;
3440
2449
    }
3441
2450
 
3442
2451
    /*
3443
 
      CHECK TABLE command is only command where VIEW allowed here and this
 
2452
      CHECK Table command is only command where VIEW allowed here and this
3444
2453
      command use only temporary teble method for VIEWs resolving => there
3445
2454
      can't be VIEW tree substitition of join view => if opening table
3446
 
      succeed then table->table will have real TABLE pointer as value (in
 
2455
      succeed then table->table will have real Table pointer as value (in
3447
2456
      case of join view substitution table->table can be 0, but here it is
3448
2457
      impossible)
3449
2458
    */
3450
2459
    if (!table->table)
3451
2460
    {
3452
2461
      if (!thd->warn_list.elements)
3453
 
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
 
2462
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
3454
2463
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
3455
2464
      goto send_result;
3456
2465
    }
3458
2467
    if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
3459
2468
    {
3460
2469
      /* purecov: begin inspected */
3461
 
      char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
3462
 
      uint length;
 
2470
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
 
2471
      uint32_t length;
3463
2472
      protocol->prepare_for_resend();
3464
2473
      protocol->store(table_name, system_charset_info);
3465
2474
      protocol->store(operator_name, system_charset_info);
3540
2549
    lex->cleanup_after_one_table_open();
3541
2550
    thd->clear_error();  // these errors shouldn't get client
3542
2551
    {
3543
 
      List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
3544
 
      MYSQL_ERROR *err;
 
2552
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
2553
      DRIZZLE_ERROR *err;
3545
2554
      while ((err= it++))
3546
2555
      {
3547
2556
        protocol->prepare_for_resend();
3554
2563
        if (protocol->write())
3555
2564
          goto err;
3556
2565
      }
3557
 
      mysql_reset_errors(thd, true);
 
2566
      drizzle_reset_errors(thd, true);
3558
2567
    }
3559
2568
    protocol->prepare_for_resend();
3560
2569
    protocol->store(table_name, system_charset_info);
3566
2575
    case HA_ADMIN_NOT_IMPLEMENTED:
3567
2576
      {
3568
2577
        char buf[ERRMSGSIZE+20];
3569
 
        uint length=snprintf(buf, ERRMSGSIZE,
 
2578
        uint32_t length=snprintf(buf, ERRMSGSIZE,
3570
2579
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
3571
2580
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
3572
2581
        protocol->store(buf, length, system_charset_info);
3576
2585
    case HA_ADMIN_NOT_BASE_TABLE:
3577
2586
      {
3578
2587
        char buf[ERRMSGSIZE+20];
3579
 
        uint length= snprintf(buf, ERRMSGSIZE,
 
2588
        uint32_t length= snprintf(buf, ERRMSGSIZE,
3580
2589
                              ER(ER_BAD_TABLE_ERROR), table_name);
3581
2590
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
3582
2591
        protocol->store(buf, length, system_charset_info);
3623
2632
    {
3624
2633
      /*
3625
2634
        This is currently used only by InnoDB. ha_innobase::optimize() answers
3626
 
        "try with alter", so here we close the table, do an ALTER TABLE,
 
2635
        "try with alter", so here we close the table, do an ALTER Table,
3627
2636
        reopen the table and do ha_innobase::analyze() on it.
3628
2637
      */
3629
2638
      ha_autocommit_or_rollback(thd, 0);
3630
2639
      close_thread_tables(thd);
3631
 
      TABLE_LIST *save_next_local= table->next_local,
 
2640
      TableList *save_next_local= table->next_local,
3632
2641
                 *save_next_global= table->next_global;
3633
2642
      table->next_local= table->next_global= 0;
3634
2643
      tmp_disable_binlog(thd); // binlogging is done by caller if wanted
3691
2700
    case HA_ADMIN_NEEDS_ALTER:
3692
2701
    {
3693
2702
      char buf[ERRMSGSIZE];
3694
 
      uint length;
 
2703
      uint32_t length;
3695
2704
 
3696
2705
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3697
2706
      length=snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
3703
2712
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
3704
2713
      {
3705
2714
        char buf[ERRMSGSIZE+20];
3706
 
        uint length=snprintf(buf, ERRMSGSIZE,
3707
 
                             "Unknown - internal error %d during operation",
 
2715
        uint32_t length=snprintf(buf, ERRMSGSIZE,
 
2716
                             _("Unknown - internal error %d during operation"),
3708
2717
                             result_code);
3709
2718
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
3710
2719
        protocol->store(buf, length, system_charset_info);
3750
2759
}
3751
2760
 
3752
2761
 
3753
 
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
2762
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
3754
2763
{
3755
2764
  return(mysql_admin_table(thd, tables, check_opt,
3756
2765
                                "repair", TL_WRITE, 1,
3761
2770
}
3762
2771
 
3763
2772
 
3764
 
bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
2773
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
3765
2774
{
3766
2775
  return(mysql_admin_table(thd, tables, check_opt,
3767
2776
                                "optimize", TL_WRITE, 1,0,0,0,
3782
2791
   true  error
3783
2792
*/
3784
2793
 
3785
 
bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
 
2794
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
3786
2795
                             LEX_STRING *key_cache_name)
3787
2796
{
3788
2797
  HA_CHECK_OPT check_opt;
3829
2838
    0     ok
3830
2839
*/
3831
2840
 
3832
 
int reassign_keycache_tables(THD *thd __attribute__((__unused__)),
 
2841
int reassign_keycache_tables(THD *thd __attribute__((unused)),
3833
2842
                             KEY_CACHE *src_cache,
3834
2843
                             KEY_CACHE *dst_cache)
3835
2844
{
3853
2862
    @retval       0                        success
3854
2863
    @retval       1                        error
3855
2864
*/
3856
 
bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
 
2865
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
3857
2866
                                  char *dst_path, HA_CREATE_INFO *create_info)
3858
2867
{
3859
2868
  HA_CREATE_INFO local_create_info;
3860
2869
  Alter_info alter_info;
3861
2870
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
3862
 
  uint keys= schema_table->table->s->keys;
3863
 
  uint db_options= 0;
 
2871
  uint32_t keys= schema_table->table->s->keys;
 
2872
  uint32_t db_options= 0;
3864
2873
 
3865
 
  bzero((char*) &local_create_info, sizeof(local_create_info));
 
2874
  memset(&local_create_info, 0, sizeof(local_create_info));
3866
2875
  local_create_info.db_type= schema_table->table->s->db_type();
3867
2876
  local_create_info.row_type= schema_table->table->s->row_type;
3868
2877
  local_create_info.default_table_charset=default_charset_info;
3877
2886
                                 &schema_table->table->s->key_info, &keys, 0))
3878
2887
    return(1);
3879
2888
  local_create_info.max_rows= 0;
3880
 
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
 
2889
  if (mysql_create_frm(thd, dst_path, NULL, NULL,
3881
2890
                       &local_create_info, alter_info.create_list,
3882
2891
                       keys, schema_table->table->s->key_info,
3883
2892
                       schema_table->table->file))
3901
2910
    true  error
3902
2911
*/
3903
2912
 
3904
 
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
 
2913
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
3905
2914
                             HA_CREATE_INFO *create_info)
3906
2915
{
3907
 
  TABLE *name_lock= 0;
 
2916
  Table *name_lock= 0;
3908
2917
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
3909
 
  uint dst_path_length;
 
2918
  uint32_t dst_path_length;
3910
2919
  char *db= table->db;
3911
2920
  char *table_name= table->table_name;
3912
2921
  int  err;
3913
2922
  bool res= true;
3914
 
  uint not_used;
3915
 
 
3916
 
 
3917
 
  /* CREATE TABLE ... LIKE is not allowed for views. */
3918
 
  src_table->required_type= FRMTYPE_TABLE;
 
2923
  uint32_t not_used;
3919
2924
 
3920
2925
  /*
3921
2926
    By opening source table we guarantee that it exists and no concurrent
3929
2934
  if (open_tables(thd, &src_table, &not_used, 0))
3930
2935
    return(true);
3931
2936
 
3932
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
 
2937
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
3933
2938
 
3934
2939
  /* 
3935
2940
    Check that destination tables does not exist. Note that its name
3967
2972
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
3968
2973
    during the call to ha_create_table(). See bug #28614 for more info.
3969
2974
  */
3970
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
2975
  pthread_mutex_lock(&LOCK_open);
3971
2976
  if (src_table->schema_table)
3972
2977
  {
3973
2978
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
3974
2979
    {
3975
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
2980
      pthread_mutex_unlock(&LOCK_open);
3976
2981
      goto err;
3977
2982
    }
3978
2983
  }
3982
2987
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
3983
2988
    else
3984
2989
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
3985
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
2990
    pthread_mutex_unlock(&LOCK_open);
3986
2991
    goto err;
3987
2992
  }
3988
2993
 
3995
3000
  if (thd->variables.keep_files_on_create)
3996
3001
    create_info->options|= HA_CREATE_KEEP_FILES;
3997
3002
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
3998
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3003
  pthread_mutex_unlock(&LOCK_open);
3999
3004
 
4000
3005
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
4001
3006
  {
4050
3055
          of this function.
4051
3056
        */
4052
3057
        table->table= name_lock;
4053
 
        VOID(pthread_mutex_lock(&LOCK_open));
 
3058
        pthread_mutex_lock(&LOCK_open);
4054
3059
        if (reopen_name_locked_table(thd, table, false))
4055
3060
        {
4056
 
          VOID(pthread_mutex_unlock(&LOCK_open));
 
3061
          pthread_mutex_unlock(&LOCK_open);
4057
3062
          goto err;
4058
3063
        }
4059
 
        VOID(pthread_mutex_unlock(&LOCK_open));
 
3064
        pthread_mutex_unlock(&LOCK_open);
4060
3065
 
4061
3066
        int result= store_create_info(thd, table, &query,
4062
3067
                                               create_info);
4080
3085
table_exists:
4081
3086
  if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
4082
3087
  {
4083
 
    char warn_buff[MYSQL_ERRMSG_SIZE];
 
3088
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
4084
3089
    snprintf(warn_buff, sizeof(warn_buff),
4085
3090
             ER(ER_TABLE_EXISTS_ERROR), table_name);
4086
 
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
3091
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4087
3092
                 ER_TABLE_EXISTS_ERROR,warn_buff);
4088
3093
    res= false;
4089
3094
  }
4101
3106
}
4102
3107
 
4103
3108
 
4104
 
bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
3109
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
4105
3110
{
4106
3111
  thr_lock_type lock_type = TL_READ_NO_INSERT;
4107
3112
 
4111
3116
}
4112
3117
 
4113
3118
 
4114
 
bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
 
3119
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
4115
3120
{
4116
3121
  thr_lock_type lock_type = TL_READ_NO_INSERT;
4117
3122
 
4125
3130
/* table_list should contain just one table */
4126
3131
static int
4127
3132
mysql_discard_or_import_tablespace(THD *thd,
4128
 
                                   TABLE_LIST *table_list,
 
3133
                                   TableList *table_list,
4129
3134
                                   enum tablespace_op_type tablespace_op)
4130
3135
{
4131
 
  TABLE *table;
4132
 
  my_bool discard;
 
3136
  Table *table;
 
3137
  bool discard;
4133
3138
  int error;
4134
3139
 
4135
3140
  /*
4136
3141
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
4137
 
    ALTER TABLE
 
3142
    ALTER Table
4138
3143
  */
4139
3144
 
4140
3145
  thd_proc_info(thd, "discard_or_import_tablespace");
4159
3164
  if (error)
4160
3165
    goto err;
4161
3166
 
4162
 
  /* The ALTER TABLE is always in its own transaction */
 
3167
  /* The ALTER Table is always in its own transaction */
4163
3168
  error = ha_autocommit_or_rollback(thd, 0);
4164
3169
  if (end_active_trans(thd))
4165
3170
    error=1;
4188
3193
 
4189
3194
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
4190
3195
{
4191
 
  uint flags= alter_info->flags;
 
3196
  uint32_t flags= alter_info->flags;
4192
3197
 
4193
3198
  if (ALTER_ADD_COLUMN & flags)
4194
3199
    *alter_flags|= HA_ADD_COLUMN;
4233
3238
   table has in arguments create_list, key_list and create_info.
4234
3239
 
4235
3240
   By comparing the changes between the original and new table
4236
 
   we can determine how much it has changed after ALTER TABLE
 
3241
   we can determine how much it has changed after ALTER Table
4237
3242
   and whether we need to make a copy of the table, or just change
4238
3243
   the .frm file.
4239
3244
 
4251
3256
static
4252
3257
bool
4253
3258
compare_tables(THD *thd,
4254
 
               TABLE *table,
 
3259
               Table *table,
4255
3260
               Alter_info *alter_info,
4256
3261
                           HA_CREATE_INFO *create_info,
4257
 
               uint order_num,
 
3262
               uint32_t order_num,
4258
3263
               HA_ALTER_FLAGS *alter_flags,
4259
3264
               HA_ALTER_INFO *ha_alter_info,
4260
 
               uint *table_changes)
 
3265
               uint32_t *table_changes)
4261
3266
{
4262
3267
  Field **f_ptr, *field;
4263
 
  uint table_changes_local= 0;
 
3268
  uint32_t table_changes_local= 0;
4264
3269
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
4265
3270
  Create_field *new_field;
4266
3271
  KEY_PART_INFO *key_part;
4284
3289
      like to keep compare_tables() idempotent (not altering any
4285
3290
      of the arguments) we create a copy of alter_info here and
4286
3291
      pass it to mysql_prepare_create_table, then use the result
4287
 
      to evaluate possibility of fast ALTER TABLE, and then
 
3292
      to evaluate possibility of fast ALTER Table, and then
4288
3293
      destroy the copy.
4289
3294
    */
4290
3295
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
4291
3296
    THD *thd= table->in_use;
4292
 
    uint db_options= 0; /* not used */
 
3297
    uint32_t db_options= 0; /* not used */
4293
3298
    /* Create the prepared information. */
4294
3299
    if (mysql_prepare_create_table(thd, create_info,
4295
3300
                                   &tmp_alter_info,
4317
3322
 
4318
3323
  /*
4319
3324
    Some very basic checks. If number of fields changes, or the
4320
 
    handler, we need to run full ALTER TABLE. In the future
 
3325
    handler, we need to run full ALTER Table. In the future
4321
3326
    new fields can be added and old dropped without copy, but
4322
3327
    not yet.
4323
3328
 
4324
 
    Test also that engine was not given during ALTER TABLE, or
 
3329
    Test also that engine was not given during ALTER Table, or
4325
3330
    we are force to run regular alter table (copy).
4326
 
    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
 
3331
    E.g. ALTER Table tbl_name ENGINE=MyISAM.
4327
3332
 
4328
3333
    For the following ones we also want to run regular alter table:
4329
 
    ALTER TABLE tbl_name ORDER BY ..
4330
 
    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
 
3334
    ALTER Table tbl_name order_st BY ..
 
3335
    ALTER Table tbl_name CONVERT TO CHARACTER SET ..
4331
3336
 
4332
3337
    At the moment we can't handle altering temporary tables without a copy.
4333
 
    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
 
3338
    We also test if OPTIMIZE Table was given and was mapped to alter table.
4334
3339
    In that case we always do full copy.
4335
3340
 
4336
3341
    There was a bug prior to mysql-4.0.25. Number of null fields was
4392
3397
    /* Don't pack rows in old tables if the user has requested this. */
4393
3398
    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
4394
3399
        (new_field->flags & BLOB_FLAG) ||
4395
 
        (new_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
3400
        (new_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
4396
3401
      create_info->table_options|= HA_OPTION_PACK_RECORD;
4397
3402
 
4398
3403
    /* Check how fields have been modified */
4598
3603
 
4599
3604
 
4600
3605
/*
4601
 
  Manages enabling/disabling of indexes for ALTER TABLE
 
3606
  Manages enabling/disabling of indexes for ALTER Table
4602
3607
 
4603
3608
  SYNOPSIS
4604
3609
    alter_table_manage_keys()
4613
3618
*/
4614
3619
 
4615
3620
static
4616
 
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
 
3621
bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
4617
3622
                             enum enum_enable_or_disable keys_onoff)
4618
3623
{
4619
3624
  int error= 0;
4631
3636
 
4632
3637
  if (error == HA_ERR_WRONG_COMMAND)
4633
3638
  {
4634
 
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
3639
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4635
3640
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4636
3641
                        table->s->table_name.str);
4637
3642
    error= 0;
4642
3647
}
4643
3648
 
4644
3649
int create_temporary_table(THD *thd,
4645
 
                           TABLE *table,
 
3650
                           Table *table,
4646
3651
                           char *new_db,
4647
3652
                           char *tmp_name,
4648
3653
                           HA_CREATE_INFO *create_info,
4683
3688
    if (create_info->index_file_name)
4684
3689
    {
4685
3690
      /* Fix index_file_name to have 'tmp_name' as basename */
4686
 
      strmov(index_file, tmp_name);
 
3691
      my_stpcpy(index_file, tmp_name);
4687
3692
      create_info->index_file_name=fn_same(index_file,
4688
3693
                                           create_info->index_file_name,
4689
3694
                                           1);
4691
3696
    if (create_info->data_file_name)
4692
3697
    {
4693
3698
      /* Fix data_file_name to have 'tmp_name' as basename */
4694
 
      strmov(data_file, tmp_name);
 
3699
      my_stpcpy(data_file, tmp_name);
4695
3700
      create_info->data_file_name=fn_same(data_file,
4696
3701
                                          create_info->data_file_name,
4697
3702
                                          1);
4733
3738
    The temporary table is created without storing it in any storage engine
4734
3739
    and is opened only to get the table struct and frm file reference.
4735
3740
*/
4736
 
TABLE *create_altered_table(THD *thd,
4737
 
                            TABLE *table,
 
3741
Table *create_altered_table(THD *thd,
 
3742
                            Table *table,
4738
3743
                            char *new_db,
4739
3744
                            HA_CREATE_INFO *create_info,
4740
3745
                            Alter_info *alter_info,
4742
3747
{
4743
3748
  int error;
4744
3749
  HA_CREATE_INFO altered_create_info(*create_info);
4745
 
  TABLE *altered_table;
 
3750
  Table *altered_table;
4746
3751
  char tmp_name[80];
4747
3752
  char path[FN_REFLEN];
4748
3753
 
4796
3801
    the table.
4797
3802
*/
4798
3803
int mysql_fast_or_online_alter_table(THD *thd,
4799
 
                                     TABLE *table,
4800
 
                                     TABLE *altered_table,
 
3804
                                     Table *table,
 
3805
                                     Table *altered_table,
4801
3806
                                     HA_CREATE_INFO *create_info,
4802
3807
                                     HA_ALTER_INFO *alter_info,
4803
3808
                                     HA_ALTER_FLAGS *ha_alter_flags,
4805
3810
{
4806
3811
  int error= 0;
4807
3812
  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER)?true:false;
4808
 
  TABLE *t_table;
 
3813
  Table *t_table;
4809
3814
 
4810
3815
  if (online)
4811
3816
  {
4840
3845
    The final .frm file is already created as a temporary file
4841
3846
    and will be renamed to the original table name.
4842
3847
  */
4843
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
3848
  pthread_mutex_lock(&LOCK_open);
4844
3849
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4845
3850
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4846
3851
                          keys_onoff);
4854
3859
                         table->s->table_name.str, FN_FROM_IS_TMP))
4855
3860
  {
4856
3861
    error= 1;
4857
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3862
    pthread_mutex_unlock(&LOCK_open);
4858
3863
    goto err;
4859
3864
  }
4860
3865
  broadcast_refresh();
4861
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3866
  pthread_mutex_unlock(&LOCK_open);
4862
3867
 
4863
3868
  /*
4864
 
    The ALTER TABLE is always in its own transaction.
 
3869
    The ALTER Table is always in its own transaction.
4865
3870
    Commit must not be called while LOCK_open is locked. It could call
4866
3871
    wait_if_global_read_lock(), which could create a deadlock if called
4867
3872
    with LOCK_open.
4874
3879
    goto err;
4875
3880
  if (online)
4876
3881
  {
4877
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3882
    pthread_mutex_lock(&LOCK_open);
4878
3883
    if (reopen_table(table))
4879
3884
    {
4880
3885
      error= -1;
4881
3886
      goto err;
4882
3887
    }
4883
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3888
    pthread_mutex_unlock(&LOCK_open);
4884
3889
    t_table= table;
4885
3890
 
4886
3891
   /*
4894
3899
 
4895
3900
    /*
4896
3901
      We are going to reopen table down on the road, so we have to restore
4897
 
      state of the TABLE object which we used for obtaining of handler
 
3902
      state of the Table object which we used for obtaining of handler
4898
3903
      object to make it suitable for reopening.
4899
3904
    */
4900
3905
    assert(t_table == table);
4901
3906
    table->open_placeholder= 1;
4902
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3907
    pthread_mutex_lock(&LOCK_open);
4903
3908
    close_handle_and_leave_table_as_lock(table);
4904
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3909
    pthread_mutex_unlock(&LOCK_open);
4905
3910
  }
4906
3911
 
4907
3912
 err:
4912
3917
 
4913
3918
 
4914
3919
/**
4915
 
  Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
 
3920
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
4916
3921
 
4917
 
  This function transforms parse output of ALTER TABLE - lists of
 
3922
  This function transforms parse output of ALTER Table - lists of
4918
3923
  columns and keys to add, drop or modify into, essentially,
4919
3924
  CREATE TABLE definition - a list of columns and keys of the new
4920
3925
  table. While doing so, it also performs some (bug not all)
4921
3926
  semantic checks.
4922
3927
 
4923
3928
  This function is invoked when we know that we're going to
4924
 
  perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
 
3929
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
4925
3930
  is not possible, perhaps because the ALTER statement contains
4926
3931
  instructions that require change in table data, not only in
4927
3932
  table definition or indexes.
4932
3937
                              Used as an interface to the storage engine
4933
3938
                              to acquire additional information about
4934
3939
                              the original table.
4935
 
  @param[in,out]  create_info A blob with CREATE/ALTER TABLE
 
3940
  @param[in,out]  create_info A blob with CREATE/ALTER Table
4936
3941
                              parameters
4937
3942
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
4938
3943
                              Originally create_info was used only in
4939
 
                              CREATE TABLE and alter_info only in ALTER TABLE.
 
3944
                              CREATE TABLE and alter_info only in ALTER Table.
4940
3945
                              But since ALTER might end-up doing CREATE,
4941
3946
                              this distinction is gone and we just carry
4942
3947
                              around two structures.
4948
3953
    Prepares alter_info->create_list and alter_info->key_list with
4949
3954
    columns and keys of the new table.
4950
3955
  @retval true   error, out of memory or a semantical error in ALTER
4951
 
                 TABLE instructions
 
3956
                 Table instructions
4952
3957
  @retval false  success
4953
3958
*/
4954
3959
 
4955
3960
static bool
4956
 
mysql_prepare_alter_table(THD *thd, TABLE *table,
 
3961
mysql_prepare_alter_table(THD *thd, Table *table,
4957
3962
                          HA_CREATE_INFO *create_info,
4958
3963
                          Alter_info *alter_info)
4959
3964
{
4968
3973
  List_iterator<Create_field> find_it(new_create_list);
4969
3974
  List_iterator<Create_field> field_it(new_create_list);
4970
3975
  List<Key_part_spec> key_parts;
4971
 
  uint db_create_options= (table->s->db_create_options
 
3976
  uint32_t db_create_options= (table->s->db_create_options
4972
3977
                           & ~(HA_OPTION_PACK_RECORD));
4973
 
  uint used_fields= create_info->used_fields;
 
3978
  uint32_t used_fields= create_info->used_fields;
4974
3979
  KEY *key_info=table->key_info;
4975
3980
  bool rc= true;
4976
3981
 
4983
3988
    create_info->max_rows= table->s->max_rows;
4984
3989
  if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
4985
3990
    create_info->avg_row_length= table->s->avg_row_length;
 
3991
  if (!(used_fields & HA_CREATE_USED_BLOCK_SIZE))
 
3992
    create_info->block_size= table->s->block_size;
4986
3993
  if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
4987
3994
    create_info->default_table_charset= table->s->table_charset;
4988
3995
  if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
4993
4000
  }
4994
4001
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
4995
4002
    create_info->key_block_size= table->s->key_block_size;
4996
 
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
4997
 
    create_info->transactional= table->s->transactional;
4998
4003
 
4999
4004
  restore_record(table, s->default_values);     // Empty record for DEFAULT
5000
4005
  Create_field *def;
5005
4010
  Field **f_ptr,*field;
5006
4011
  for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
5007
4012
    {
5008
 
    if (field->type() == MYSQL_TYPE_STRING)
5009
 
      create_info->varchar= true;
5010
4013
    /* Check if field should be dropped */
5011
4014
    Alter_drop *drop;
5012
4015
    drop_it.rewind();
5064
4067
        }
5065
4068
      if (alter)
5066
4069
        {
5067
 
        if (def->sql_type == MYSQL_TYPE_BLOB)
 
4070
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
5068
4071
        {
5069
4072
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
5070
4073
          goto err;
5090
4093
      either has a default value or the '0000-00-00' is allowed by the
5091
4094
      set sql mode.
5092
4095
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
5093
 
      flag to allow ALTER TABLE only if the table to be altered is empty.
 
4096
      flag to allow ALTER Table only if the table to be altered is empty.
5094
4097
      */
5095
 
    if ((def->sql_type == MYSQL_TYPE_NEWDATE ||
5096
 
         def->sql_type == MYSQL_TYPE_DATETIME) &&
 
4098
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
 
4099
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
5097
4100
         !alter_info->datetime_field &&
5098
4101
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
5099
4102
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
5122
4125
      find_it.after(def);                       // Put element after this
5123
4126
      /*
5124
4127
        XXX: hack for Bug#28427.
5125
 
        If column order has changed, force OFFLINE ALTER TABLE
 
4128
        If column order has changed, force OFFLINE ALTER Table
5126
4129
        without querying engine capabilities.  If we ever have an
5127
 
        engine that supports online ALTER TABLE CHANGE COLUMN
 
4130
        engine that supports online ALTER Table CHANGE COLUMN
5128
4131
        <name> AFTER <name1> (Falcon?), this fix will effectively
5129
4132
        disable the capability.
5130
4133
        TODO: detect the situation in compare_tables, behave based
5156
4159
    for which some fields exists.
5157
4160
    */
5158
4161
 
5159
 
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
 
4162
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
5160
4163
    {
5161
4164
    char *key_name= key_info->name;
5162
4165
    Alter_drop *drop;
5175
4178
 
5176
4179
    KEY_PART_INFO *key_part= key_info->key_part;
5177
4180
    key_parts.empty();
5178
 
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
 
4181
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
5179
4182
    {
5180
4183
      if (!key_part->field)
5181
4184
        continue;                               // Wrong field (from UNIREG)
5196
4199
      }
5197
4200
      if (!cfield)
5198
4201
        continue;                               // Field is removed
5199
 
      uint key_part_length=key_part->length;
 
4202
      uint32_t key_part_length=key_part->length;
5200
4203
      if (cfield->field)                        // Not new field
5201
4204
      {
5202
4205
        /*
5229
4232
      KEY_CREATE_INFO key_create_info;
5230
4233
      Key *key;
5231
4234
      enum Key::Keytype key_type;
5232
 
      bzero((char*) &key_create_info, sizeof(key_create_info));
 
4235
      memset(&key_create_info, 0, sizeof(key_create_info));
5233
4236
 
5234
4237
      key_create_info.algorithm= key_info->algorithm;
5235
4238
      if (key_info->flags & HA_USES_BLOCK_SIZE)
5326
4329
      table_list       The table to change.
5327
4330
      alter_info       Lists of fields, keys to be changed, added
5328
4331
                       or dropped.
5329
 
      order_num        How many ORDER BY fields has been specified.
5330
 
      order            List of fields to ORDER BY.
5331
 
      ignore           Whether we have ALTER IGNORE TABLE
 
4332
      order_num        How many order_st BY fields has been specified.
 
4333
      order            List of fields to order_st BY.
 
4334
      ignore           Whether we have ALTER IGNORE Table
5332
4335
 
5333
4336
  DESCRIPTION
5334
4337
    This is a veery long function and is everything but the kitchen sink :)
5335
 
    It is used to alter a table and not only by ALTER TABLE but also
 
4338
    It is used to alter a table and not only by ALTER Table but also
5336
4339
    CREATE|DROP INDEX are mapped on this function.
5337
4340
 
5338
 
    When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
 
4341
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
5339
4342
    or both, then this function short cuts its operation by renaming
5340
4343
    the table and/or enabling/disabling the keys. In this case, the FRM is
5341
4344
    not changed, directly by mysql_alter_table. However, if there is a
5357
4360
 
5358
4361
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
5359
4362
                       HA_CREATE_INFO *create_info,
5360
 
                       TABLE_LIST *table_list,
 
4363
                       TableList *table_list,
5361
4364
                       Alter_info *alter_info,
5362
 
                       uint order_num, ORDER *order, bool ignore)
 
4365
                       uint32_t order_num, order_st *order, bool ignore)
5363
4366
{
5364
 
  TABLE *table, *new_table=0, *name_lock= 0;;
 
4367
  Table *table, *new_table=0, *name_lock= 0;;
5365
4368
  int error= 0;
5366
4369
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
5367
4370
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
5369
4372
  ha_rows copied= 0,deleted= 0;
5370
4373
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
5371
4374
  legacy_db_type table_type;
5372
 
  frm_type_enum frm_type;
5373
4375
 
5374
4376
  if (table_list && table_list->schema_table)
5375
4377
  {
5392
4394
 
5393
4395
  mysql_ha_rm_tables(thd, table_list, false);
5394
4396
 
5395
 
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
 
4397
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
5396
4398
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
5397
4399
    /* Conditionally writes to binlog. */
5398
4400
    return(mysql_discard_or_import_tablespace(thd,table_list,
5399
4401
                                              alter_info->tablespace_op));
5400
4402
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
5401
 
           "/", table_name, reg_ext, NullS);
 
4403
           "/", table_name, reg_ext, NULL);
5402
4404
  (void) unpack_filename(new_name_buff, new_name_buff);
5403
4405
  /*
5404
4406
    If this is just a rename of a view, short cut to the
5405
4407
    following scenario: 1) lock LOCK_open 2) do a RENAME
5406
4408
    2) unlock LOCK_open.
5407
4409
    This is a copy-paste added to make sure
5408
 
    ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
 
4410
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
5409
4411
    as an independent branch in mysql_execute_command. The need
5410
 
    for a copy-paste arose because the main code flow of ALTER TABLE
 
4412
    for a copy-paste arose because the main code flow of ALTER Table
5411
4413
    ... RENAME tries to use open_ltable, which does not work for views
5412
4414
    (open_ltable was never modified to merge table lists of child tables
5413
4415
    into the main table list, like open_tables does).
5414
4416
    This code is wrong and will be removed, please do not copy.
5415
4417
  */
5416
 
  frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
 
4418
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
5417
4419
 
5418
4420
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
5419
4421
    return(true);
5420
4422
  table->use_all_columns();
5421
4423
 
5422
 
  /*
5423
 
    Prohibit changing of the UNION list of a non-temporary MERGE table
5424
 
    under LOCK tables. It would be quite difficult to reuse a shrinked
5425
 
    set of tables from the old table or to open a new TABLE object for
5426
 
    an extended list and verify that they belong to locked tables.
5427
 
  */
5428
 
  if (thd->locked_tables &&
5429
 
      (create_info->used_fields & HA_CREATE_USED_UNION) &&
5430
 
      (table->s->tmp_table == NO_TMP_TABLE))
5431
 
  {
5432
 
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
5433
 
    return(true);
5434
 
  }
5435
 
 
5436
4424
  /* Check that we are not trying to rename to an existing table */
5437
4425
  if (new_name)
5438
4426
  {
5439
 
    strmov(new_name_buff,new_name);
5440
 
    strmov(new_alias= new_alias_buff, new_name);
 
4427
    my_stpcpy(new_name_buff,new_name);
 
4428
    my_stpcpy(new_alias= new_alias_buff, new_name);
5441
4429
    if (lower_case_table_names)
5442
4430
    {
5443
4431
      if (lower_case_table_names != 2)
5503
4491
    goto err;
5504
4492
  new_db_type= create_info->db_type;
5505
4493
 
5506
 
  if (new_db_type != old_db_type ||
 
4494
  if (new_db_type != old_db_type &&
5507
4495
      !table->file->can_switch_engines())
5508
4496
  {
 
4497
    assert(0);
5509
4498
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
5510
4499
    goto err;
5511
4500
  }
5530
4519
    case ENABLE:
5531
4520
      /*
5532
4521
        wait_while_table_is_used() ensures that table being altered is
5533
 
        opened only by this thread and that TABLE::TABLE_SHARE::version
5534
 
        of TABLE object corresponding to this table is 0.
 
4522
        opened only by this thread and that Table::TABLE_SHARE::version
 
4523
        of Table object corresponding to this table is 0.
5535
4524
        The latter guarantees that no DML statement will open this table
5536
 
        until ALTER TABLE finishes (i.e. until close_thread_tables())
 
4525
        until ALTER Table finishes (i.e. until close_thread_tables())
5537
4526
        while the fact that the table is still open gives us protection
5538
4527
        from concurrent DDL statements.
5539
4528
      */
5540
 
      VOID(pthread_mutex_lock(&LOCK_open));
 
4529
      pthread_mutex_lock(&LOCK_open);
5541
4530
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5542
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
4531
      pthread_mutex_unlock(&LOCK_open);
5543
4532
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
5544
4533
      /* COND_refresh will be signaled in close_thread_tables() */
5545
4534
      break;
5546
4535
    case DISABLE:
5547
 
      VOID(pthread_mutex_lock(&LOCK_open));
 
4536
      pthread_mutex_lock(&LOCK_open);
5548
4537
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5549
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
4538
      pthread_mutex_unlock(&LOCK_open);
5550
4539
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
5551
4540
      /* COND_refresh will be signaled in close_thread_tables() */
5552
4541
      break;
5558
4547
    if (error == HA_ERR_WRONG_COMMAND)
5559
4548
    {
5560
4549
      error= 0;
5561
 
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
4550
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5562
4551
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
5563
4552
                          table->alias);
5564
4553
    }
5565
4554
 
5566
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
4555
    pthread_mutex_lock(&LOCK_open);
5567
4556
    /*
5568
4557
      Unlike to the above case close_cached_table() below will remove ALL
5569
 
      instances of TABLE from table cache (it will also remove table lock
 
4558
      instances of Table from table cache (it will also remove table lock
5570
4559
      held by this thread). So to make actual table renaming and writing
5571
4560
      to binlog atomic we have to put them into the same critical section
5572
4561
      protected by LOCK_open mutex. This also removes gap for races between
5601
4590
          error= -1;
5602
4591
        else if (0)
5603
4592
      {
5604
 
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
5605
 
                                  table_name, 0));
 
4593
          mysql_rename_table(old_db_type, new_db, new_alias, db,
 
4594
                             table_name, 0);
5606
4595
          error= -1;
5607
4596
      }
5608
4597
    }
5611
4600
    if (error == HA_ERR_WRONG_COMMAND)
5612
4601
  {
5613
4602
      error= 0;
5614
 
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
4603
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5615
4604
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
5616
4605
                          table->alias);
5617
4606
  }
5628
4617
    }
5629
4618
    if (name_lock)
5630
4619
      unlink_open_table(thd, name_lock, false);
5631
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4620
    pthread_mutex_unlock(&LOCK_open);
5632
4621
    table_list->table= NULL;                    // For query cache
5633
4622
    return(error);
5634
4623
  }
5636
4625
  /* We have to do full alter table. */
5637
4626
 
5638
4627
    /*
5639
 
    If the old table had partitions and we are doing ALTER TABLE ...
 
4628
    If the old table had partitions and we are doing ALTER Table ...
5640
4629
    engine= <new_engine>, the new table must preserve the original
5641
4630
    partitioning. That means that the new engine is still the
5642
4631
    partitioning engine, not the engine specified in the parser.
5668
4657
 
5669
4658
  if (alter_info->build_method != HA_BUILD_OFFLINE)
5670
4659
  {
5671
 
    TABLE *altered_table= 0;
 
4660
    Table *altered_table= 0;
5672
4661
    HA_ALTER_INFO ha_alter_info;
5673
4662
    HA_ALTER_FLAGS ha_alter_flags;
5674
 
    uint table_changes= IS_EQUAL_YES;
 
4663
    uint32_t table_changes= IS_EQUAL_YES;
5675
4664
    bool need_copy_table= true;
5676
4665
    /* Check how much the tables differ. */
5677
4666
    if (compare_tables(thd, table, alter_info,
5720
4709
        /*
5721
4710
          @todo: Currently we always acquire an exclusive name
5722
4711
          lock on the table metadata when performing fast or online
5723
 
          ALTER TABLE. In future we may consider this unnecessary,
 
4712
          ALTER Table. In future we may consider this unnecessary,
5724
4713
          and narrow the scope of the exclusive name lock to only
5725
4714
          cover manipulation with .frms. Storage engine API
5726
4715
          call check_if_supported_alter has provision for this
5744
4733
      }
5745
4734
 
5746
4735
    }
5747
 
    /* TODO need to check if changes can be handled as fast ALTER TABLE */
 
4736
    /* TODO need to check if changes can be handled as fast ALTER Table */
5748
4737
    if (!altered_table)
5749
4738
      need_copy_table= true;
5750
4739
 
5802
4791
  /* Open the table so we need to copy the data to it. */
5803
4792
  if (table->s->tmp_table)
5804
4793
  {
5805
 
    TABLE_LIST tbl;
5806
 
    bzero((void*) &tbl, sizeof(tbl));
 
4794
    TableList tbl;
 
4795
    memset(&tbl, 0, sizeof(tbl));
5807
4796
    tbl.db= new_db;
5808
4797
    tbl.table_name= tbl.alias= tmp_name;
5809
4798
    /* Table is in thd->temporary_tables */
5810
 
    new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
5811
 
                          MYSQL_LOCK_IGNORE_FLUSH);
 
4799
    new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
5812
4800
  }
5813
4801
  else
5814
4802
  {
5833
4821
  */
5834
4822
  if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
5835
4823
  {
5836
 
    /* We don't want update TIMESTAMP fields during ALTER TABLE. */
 
4824
    /* We don't want update TIMESTAMP fields during ALTER Table. */
5837
4825
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
5838
4826
    new_table->next_number_field=new_table->found_next_number_field;
5839
4827
    error= copy_data_between_tables(table, new_table,
5844
4832
  }
5845
4833
  else
5846
4834
  {
5847
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
4835
    pthread_mutex_lock(&LOCK_open);
5848
4836
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
5849
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4837
    pthread_mutex_unlock(&LOCK_open);
5850
4838
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
5851
4839
                            alter_info->keys_onoff);
5852
4840
    error= ha_autocommit_or_rollback(thd, 0);
5884
4872
      Note that MERGE tables do not have their children attached here.
5885
4873
    */
5886
4874
    intern_close_table(new_table);
5887
 
    my_free(new_table,MYF(0));
 
4875
    free(new_table);
5888
4876
  }
5889
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
4877
  pthread_mutex_lock(&LOCK_open);
5890
4878
  if (error)
5891
4879
  {
5892
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
5893
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4880
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
4881
    pthread_mutex_unlock(&LOCK_open);
5894
4882
    goto err;
5895
4883
  }
5896
4884
 
5901
4889
       with exclusive name-locks.
5902
4890
    3) Rename the old table to a temp name, rename the new one to the
5903
4891
       old name.
5904
 
    4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
 
4892
    4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
5905
4893
       we reopen new version of table.
5906
4894
    5) Write statement to the binary log.
5907
 
    6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
 
4895
    6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
5908
4896
       remove name-locks from list of open tables and table cache.
5909
4897
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
5910
4898
       call to remove name-locks from table cache and list of open table.
5927
4915
    mysql_rename_table(), because we just juggle with the FRM and nothing
5928
4916
    more. If we have an intermediate table, then we notify the SE that
5929
4917
    it should become the actual table. Later, we will recycle the old table.
5930
 
    However, in case of ALTER TABLE RENAME there might be no intermediate
 
4918
    However, in case of ALTER Table RENAME there might be no intermediate
5931
4919
    table. This is when the old and new tables are compatible, according to
5932
4920
    compare_table(). Then, we need one additional call to
5933
4921
    mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
5939
4927
                         FN_TO_IS_TMP))
5940
4928
  {
5941
4929
    error=1;
5942
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
4930
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5943
4931
  }
5944
4932
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
5945
4933
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
5946
4934
  {
5947
4935
    /* Try to get everything back. */
5948
4936
    error=1;
5949
 
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
5950
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
5951
 
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
5952
 
                            FN_FROM_IS_TMP));
 
4937
    quick_rm_table(new_db_type,new_db,new_alias, 0);
 
4938
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
4939
    mysql_rename_table(old_db_type, db, old_name, db, alias,
 
4940
                       FN_FROM_IS_TMP);
5953
4941
  }
5954
4942
 
5955
4943
  if (error)
5958
4946
    goto err_with_placeholders;
5959
4947
  }
5960
4948
 
5961
 
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
 
4949
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
5962
4950
 
5963
4951
end_online:
5964
4952
  if (thd->locked_tables && new_name == table_name && new_db == db)
5969
4957
    if (error)
5970
4958
      goto err_with_placeholders;
5971
4959
  }
5972
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
4960
  pthread_mutex_unlock(&LOCK_open);
5973
4961
 
5974
4962
  thd_proc_info(thd, "end");
5975
4963
 
5976
 
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
5977
 
                      thd->query, thd->query_length,
5978
 
                      db, table_name);
5979
 
 
5980
4964
  assert(!(mysql_bin_log.is_open() &&
5981
4965
                thd->current_stmt_binlog_row_based &&
5982
4966
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
5990
4974
      shutdown. But we do not need to attach MERGE children.
5991
4975
    */
5992
4976
    char path[FN_REFLEN];
5993
 
    TABLE *t_table;
 
4977
    Table *t_table;
5994
4978
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
5995
4979
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
5996
4980
    if (t_table)
5997
4981
    {
5998
4982
      intern_close_table(t_table);
5999
 
      my_free(t_table, MYF(0));
 
4983
      free(t_table);
6000
4984
    }
6001
4985
    else
6002
 
      sql_print_warning("Could not open table %s.%s after rename\n",
 
4986
      sql_print_warning(_("Could not open table %s.%s after rename\n"),
6003
4987
                        new_db,table_name);
6004
4988
    ha_flush_logs(old_db_type);
6005
4989
  }
6008
4992
  if (thd->locked_tables && (new_name != table_name || new_db != db))
6009
4993
  {
6010
4994
    /*
6011
 
      If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
 
4995
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
6012
4996
      to remove placeholders for the old table and for the target table
6013
4997
      from the list of open tables and table cache. If we are not under
6014
4998
      LOCK TABLES we can rely on close_thread_tables() doing this job.
6034
5018
    close_temporary_table(thd, new_table, 1, 1);
6035
5019
  }
6036
5020
  else
6037
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5021
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
6038
5022
 
6039
5023
err:
6040
5024
  /*
6046
5030
  if (alter_info->error_if_not_empty && thd->row_count)
6047
5031
  {
6048
5032
    const char *f_val= 0;
6049
 
    enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
 
5033
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
6050
5034
    switch (alter_info->datetime_field->sql_type)
6051
5035
    {
6052
 
      case MYSQL_TYPE_NEWDATE:
 
5036
      case DRIZZLE_TYPE_NEWDATE:
6053
5037
        f_val= "0000-00-00";
6054
 
        t_type= MYSQL_TIMESTAMP_DATE;
 
5038
        t_type= DRIZZLE_TIMESTAMP_DATE;
6055
5039
        break;
6056
 
      case MYSQL_TYPE_DATETIME:
 
5040
      case DRIZZLE_TYPE_DATETIME:
6057
5041
        f_val= "0000-00-00 00:00:00";
6058
 
        t_type= MYSQL_TIMESTAMP_DATETIME;
 
5042
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
6059
5043
        break;
6060
5044
      default:
6061
5045
        /* Shouldn't get here. */
6063
5047
    }
6064
5048
    bool save_abort_on_warning= thd->abort_on_warning;
6065
5049
    thd->abort_on_warning= true;
6066
 
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
 
5050
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
6067
5051
                                 f_val, strlength(f_val), t_type,
6068
5052
                                 alter_info->datetime_field->field_name);
6069
5053
    thd->abort_on_warning= save_abort_on_warning;
6085
5069
  unlink_open_table(thd, table, false);
6086
5070
  if (name_lock)
6087
5071
    unlink_open_table(thd, name_lock, false);
6088
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
5072
  pthread_mutex_unlock(&LOCK_open);
6089
5073
  return(true);
6090
5074
}
6091
5075
/* mysql_alter_table */
6092
5076
 
6093
5077
static int
6094
 
copy_data_between_tables(TABLE *from,TABLE *to,
 
5078
copy_data_between_tables(Table *from,Table *to,
6095
5079
                         List<Create_field> &create,
6096
5080
                         bool ignore,
6097
 
                         uint order_num, ORDER *order,
 
5081
                         uint32_t order_num, order_st *order,
6098
5082
                         ha_rows *copied,
6099
5083
                         ha_rows *deleted,
6100
5084
                         enum enum_enable_or_disable keys_onoff,
6104
5088
  Copy_field *copy,*copy_end;
6105
5089
  ulong found_count,delete_count;
6106
5090
  THD *thd= current_thd;
6107
 
  uint length= 0;
 
5091
  uint32_t length= 0;
6108
5092
  SORT_FIELD *sortorder;
6109
5093
  READ_RECORD info;
6110
 
  TABLE_LIST   tables;
 
5094
  TableList   tables;
6111
5095
  List<Item>   fields;
6112
5096
  List<Item>   all_fields;
6113
5097
  ha_rows examined_rows;
6151
5135
    if (def->field)
6152
5136
    {
6153
5137
      if (*ptr == to->next_number_field)
6154
 
      {
6155
5138
        auto_increment_field_copied= true;
6156
 
        /*
6157
 
          If we are going to copy contents of one auto_increment column to
6158
 
          another auto_increment column it is sensible to preserve zeroes.
6159
 
          This condition also covers case when we are don't actually alter
6160
 
          auto_increment column.
6161
 
        */
6162
 
        if (def->field == from->found_next_number_field)
6163
 
          thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
6164
 
      }
 
5139
 
6165
5140
      (copy_end++)->set(*ptr,def->field,0);
6166
5141
    }
6167
5142
 
6173
5148
  {
6174
5149
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
6175
5150
    {
6176
 
      char warn_buff[MYSQL_ERRMSG_SIZE];
 
5151
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
6177
5152
      snprintf(warn_buff, sizeof(warn_buff), 
6178
 
               "ORDER BY ignored as there is a user-defined clustered index"
6179
 
               " in the table '%-.192s'", from->s->table_name.str);
6180
 
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
5153
               _("order_st BY ignored because there is a user-defined clustered "
 
5154
                 "index in the table '%-.192s'"),
 
5155
               from->s->table_name.str);
 
5156
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
6181
5157
                   warn_buff);
6182
5158
    }
6183
5159
    else
6184
5160
    {
6185
5161
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
6186
5162
                                                MYF(MY_FAE | MY_ZEROFILL));
6187
 
      bzero((char *) &tables, sizeof(tables));
 
5163
      memset(&tables, 0, sizeof(tables));
6188
5164
      tables.table= from;
6189
5165
      tables.alias= tables.table_name= from->s->table_name.str;
6190
5166
      tables.db= from->s->db.str;
6246
5222
      {
6247
5223
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
6248
5224
         {
6249
 
           uint key_nr= to->file->get_dup_key(error);
 
5225
           uint32_t key_nr= to->file->get_dup_key(error);
6250
5226
           if ((int) key_nr >= 0)
6251
5227
           {
6252
5228
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
6318
5294
 RETURN
6319
5295
    Like mysql_alter_table().
6320
5296
*/
6321
 
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
 
5297
bool mysql_recreate_table(THD *thd, TableList *table_list)
6322
5298
{
6323
5299
  HA_CREATE_INFO create_info;
6324
5300
  Alter_info alter_info;
6330
5306
  */
6331
5307
  table_list->table= NULL;
6332
5308
 
6333
 
  bzero((char*) &create_info, sizeof(create_info));
 
5309
  memset(&create_info, 0, sizeof(create_info));
6334
5310
  create_info.row_type=ROW_TYPE_NOT_USED;
6335
5311
  create_info.default_table_charset=default_charset_info;
6336
5312
  /* Force alter table to recreate table */
6337
5313
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
6338
 
  return(mysql_alter_table(thd, NullS, NullS, &create_info,
 
5314
  return(mysql_alter_table(thd, NULL, NULL, &create_info,
6339
5315
                                table_list, &alter_info, 0,
6340
 
                                (ORDER *) 0, 0));
 
5316
                                (order_st *) 0, 0));
6341
5317
}
6342
5318
 
6343
5319
 
6344
 
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
 
5320
bool mysql_checksum_table(THD *thd, TableList *tables,
6345
5321
                          HA_CHECK_OPT *check_opt)
6346
5322
{
6347
 
  TABLE_LIST *table;
 
5323
  TableList *table;
6348
5324
  List<Item> field_list;
6349
5325
  Item *item;
6350
5326
  Protocol *protocol= thd->protocol;
6362
5338
  for (table= tables; table; table= table->next_local)
6363
5339
  {
6364
5340
    char table_name[NAME_LEN*2+2];
6365
 
    TABLE *t;
 
5341
    Table *t;
6366
5342
 
6367
 
    strxmov(table_name, table->db ,".", table->table_name, NullS);
 
5343
    strxmov(table_name, table->db ,".", table->table_name, NULL);
6368
5344
 
6369
5345
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
6370
5346
    thd->clear_error();                 // these errors shouldn't get client
6390
5366
      {
6391
5367
        /* calculating table's checksum */
6392
5368
        ha_checksum crc= 0;
6393
 
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
 
5369
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
6394
5370
 
6395
5371
        t->use_all_columns();
6396
5372
 
6418
5394
              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
6419
5395
            }
6420
5396
 
6421
 
            for (uint i= 0; i < t->s->fields; i++ )
 
5397
            for (uint32_t i= 0; i < t->s->fields; i++ )
6422
5398
            {
6423
5399
              Field *f= t->field[i];
6424
 
              if ((f->type() == MYSQL_TYPE_BLOB) ||
6425
 
                  (f->type() == MYSQL_TYPE_VARCHAR))
 
5400
              if ((f->type() == DRIZZLE_TYPE_BLOB) ||
 
5401
                  (f->type() == DRIZZLE_TYPE_VARCHAR))
6426
5402
              {
6427
5403
                String tmp;
6428
5404
                f->val_str(&tmp);
6429
 
                row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
 
5405
                row_crc= my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
6430
5406
              }
6431
5407
              else
6432
5408
                row_crc= my_checksum(row_crc, f->ptr,
6469
5445
 
6470
5446
  if (req_engine && req_engine != *new_engine)
6471
5447
  {
6472
 
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
5448
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
6473
5449
                       ER_WARN_USING_OTHER_HANDLER,
6474
5450
                       ER(ER_WARN_USING_OTHER_HANDLER),
6475
5451
                       ha_resolve_storage_engine_name(*new_engine),