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