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