~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Monty Taylor
  • Date: 2008-09-16 00:00:48 UTC
  • mto: This revision was merged to the branch mainline in revision 391.
  • Revision ID: monty@inaugust.com-20080916000048-3rvrv3gv9l0ad3gs
Fixed copyright headers in drizzled/

Show diffs side-by-side

added added

removed removed

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