~drizzle-trunk/drizzle/development

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