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