~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Monty Taylor
  • Date: 2009-03-24 17:44:41 UTC
  • mto: (960.5.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 964.
  • Revision ID: mordred@inaugust.com-20090324174441-nmsq0gwjlgf7f0mt
Changed handlerton to StorageEngine.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
#include <drizzled/server_includes.h>
19
19
#include <storage/myisam/myisam.h>
20
 
#include <drizzled/sql_show.h>
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
#include <libdrizzle/gettext.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 <mysys/hash.h>
 
26
#include <drizzled/sql_lex.h>
 
27
#include <drizzled/session.h>
 
28
#include <drizzled/sql_base.h>
 
29
#include <drizzled/db.h>
 
30
#include <drizzled/lock.h>
 
31
#include <drizzled/unireg.h>
 
32
#include <drizzled/item/int.h>
 
33
#include <drizzled/item/empty_string.h>
 
34
#include <drizzled/replicator.h>
 
35
 
 
36
using namespace std;
 
37
 
 
38
extern HASH lock_db_cache;
23
39
 
24
40
int creating_table= 0;        // How many mysql_create_table are running
25
41
 
26
 
const char *primary_key_name="PRIMARY";
 
42
 
 
43
bool is_primary_key(KEY *key_info)
 
44
{
 
45
  static const char * primary_key_name="PRIMARY";
 
46
  return (strcmp(key_info->name, primary_key_name)==0);
 
47
}
 
48
 
 
49
const char* is_primary_key_name(const char* key_name)
 
50
{
 
51
  static const char * primary_key_name="PRIMARY";
 
52
  if (strcmp(key_name, primary_key_name)==0)
 
53
    return key_name;
 
54
  else
 
55
    return NULL;
 
56
}
27
57
 
28
58
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
59
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
34
64
                                    enum enum_enable_or_disable keys_onoff,
35
65
                                    bool error_if_not_empty);
36
66
 
37
 
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
38
 
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
 
67
static bool prepare_blob_field(Session *session, Create_field *sql_field);
 
68
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
39
69
static int
40
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
70
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
41
71
                           Alter_info *alter_info,
42
72
                           bool tmp_table,
43
73
                               uint32_t *db_options,
44
74
                               handler *file, KEY **key_info_buffer,
45
75
                               uint32_t *key_count, int select_field_count);
46
76
static bool
47
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
77
mysql_prepare_alter_table(Session *session, Table *table,
48
78
                          HA_CREATE_INFO *create_info,
49
79
                          Alter_info *alter_info);
50
80
 
 
81
static void set_table_default_charset(Session *session,
 
82
                                      HA_CREATE_INFO *create_info, char *db)
 
83
{
 
84
  /*
 
85
    If the table character set was not given explicitly,
 
86
    let's fetch the database default character set and
 
87
    apply it to the table.
 
88
  */
 
89
  if (!create_info->default_table_charset)
 
90
  {
 
91
    HA_CREATE_INFO db_info;
 
92
 
 
93
    load_db_opt_by_name(session, db, &db_info);
 
94
 
 
95
    create_info->default_table_charset= db_info.default_table_charset;
 
96
  }
 
97
}
 
98
 
51
99
/*
52
100
  Translate a file name to a table name (WL #1324).
53
101
 
65
113
  uint32_t errors;
66
114
  uint32_t res;
67
115
 
68
 
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
 
116
  if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
69
117
  {
70
118
    /* Temporary table name. */
71
 
    res= (my_stpncpy(to, from, to_length) - to);
 
119
    res= strlen(strncpy(to, from, to_length));
72
120
  }
73
121
  else
74
122
  {
76
124
                    system_charset_info,  to, to_length, &errors);
77
125
    if (errors) // Old 5.0 name
78
126
    {
79
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NULL) -
80
 
            to);
81
 
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
 
127
      to[0]='\0';
 
128
      strncat(to, from, to_length-1);
 
129
      res= strlen(to);
 
130
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid (old?) table or database name '%s'"), from);
82
131
    }
83
132
  }
84
133
 
98
147
  RETURN
99
148
    File name length.
100
149
*/
101
 
 
102
150
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
103
151
{
104
152
  uint32_t errors, length;
105
153
 
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
154
  length= strconvert(system_charset_info, from,
112
155
                     &my_charset_filename, to, to_length, &errors);
113
156
  if (check_if_legal_tablename(to) &&
121
164
 
122
165
 
123
166
/*
124
 
  Creates path to a file: mysql_data_dir/db/table.ext
 
167
  Creates path to a file: drizzle_data_dir/db/table.ext
125
168
 
126
169
  SYNOPSIS
127
170
   build_table_filename()
137
180
  NOTES
138
181
 
139
182
    Uses database and table name, and extension to create
140
 
    a file name in mysql_data_dir. Database and table
 
183
    a file name in drizzle_data_dir. Database and table
141
184
    names are converted from system_charset_info into "fscs".
142
185
    Unless flags indicate a temporary table name.
143
186
    'db' is always converted.
150
193
    build_tmptable_filename() for them.
151
194
 
152
195
  RETURN
153
 
    path length
 
196
    path length on success, 0 on failure
154
197
*/
155
198
 
156
199
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
157
200
                          const char *table_name, const char *ext, uint32_t flags)
158
201
{
 
202
  string table_path;
159
203
  char dbbuff[FN_REFLEN];
160
204
  char tbbuff[FN_REFLEN];
 
205
  int rootdir_len= strlen(FN_ROOTDIR);
161
206
 
162
207
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
 
    my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
 
208
    strncpy(tbbuff, table_name, sizeof(tbbuff));
164
209
  else
165
210
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
166
211
 
167
212
  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 = my_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= my_stpncpy(pos, FN_ROOTDIR, end - pos);
176
 
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NULL);
 
213
  table_path= drizzle_data_home;
 
214
  int without_rootdir= table_path.length()-rootdir_len;
 
215
 
 
216
  /* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
 
217
  if (without_rootdir >= 0)
 
218
  {
 
219
    char *tmp= (char*)table_path.c_str()+without_rootdir;
 
220
    if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
 
221
      table_path.append(FN_ROOTDIR);
 
222
  }
 
223
 
 
224
  table_path.append(dbbuff);
 
225
  table_path.append(FN_ROOTDIR);
177
226
#ifdef USE_SYMDIR
178
 
  unpack_dirname(buff, buff);
179
 
  pos= strend(buff);
 
227
  table_path.clear();
180
228
#endif
181
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
182
 
 
183
 
  return(pos - buff);
 
229
  table_path.append(tbbuff);
 
230
  table_path.append(ext);
 
231
 
 
232
  if (bufflen < table_path.length())
 
233
    return 0;
 
234
 
 
235
  strcpy(buff, table_path.c_str());
 
236
  return table_path.length();
184
237
}
185
238
 
186
239
 
187
240
/*
188
 
  Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
 
241
  Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
189
242
 
190
243
  SYNOPSIS
191
244
   build_tmptable_filename()
192
 
     thd                        The thread handle.
 
245
     session                    The thread handle.
193
246
     buff                       Where to write result in my_charset_filename.
194
247
     bufflen                    buff size
195
248
 
196
249
  NOTES
197
250
 
198
251
    Uses current_pid, thread_id, and tmp_table counter to create
199
 
    a file name in mysql_tmpdir.
 
252
    a file name in drizzle_tmpdir.
200
253
 
201
254
  RETURN
202
 
    path length
 
255
    path length on success, 0 on failure
203
256
*/
204
257
 
205
 
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
258
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
206
259
{
 
260
  uint32_t length;
 
261
  ostringstream path_str, post_tmpdir_str;
 
262
  string tmp;
207
263
 
208
 
  char *p= my_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);
 
264
  path_str << drizzle_tmpdir;
 
265
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
 
266
  post_tmpdir_str << session->thread_id << session->tmp_table++;
 
267
  tmp= post_tmpdir_str.str();
212
268
 
213
269
  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
 
  uint32_t length= unpack_filename(buff, buff);
220
 
  return(length);
 
270
    transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
 
271
 
 
272
  path_str << tmp;
 
273
 
 
274
  if (bufflen < path_str.str().length())
 
275
    length= 0;
 
276
  else
 
277
    length= unpack_filename(buff, path_str.str().c_str());
 
278
 
 
279
  return length;
221
280
}
222
281
 
223
282
/*
224
283
  SYNOPSIS
225
284
    write_bin_log()
226
 
    thd                           Thread object
 
285
    session                           Thread object
227
286
    clear_error                   is clear_error to be called
228
287
    query                         Query to log
229
288
    query_length                  Length of query
236
295
    file
237
296
*/
238
297
 
239
 
void write_bin_log(THD *thd, bool clear_error,
240
 
                   char const *query, ulong query_length)
 
298
void write_bin_log(Session *session, bool,
 
299
                   char const *query, size_t query_length)
241
300
{
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
 
  }
 
301
  (void)replicator_statement(session, query, query_length);
249
302
}
250
303
 
251
304
 
254
307
 
255
308
  SYNOPSIS
256
309
   mysql_rm_table()
257
 
   thd                  Thread handle
 
310
   session                      Thread handle
258
311
   tables               List of tables to delete
259
312
   if_exists            If 1, don't give error if one table doesn't exists
260
313
 
273
326
 
274
327
*/
275
328
 
276
 
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
 
329
bool mysql_rm_table(Session *session,TableList *tables, bool if_exists, bool drop_temporary)
277
330
{
278
331
  bool error, need_start_waiting= false;
279
332
 
280
333
  if (tables && tables->schema_table)
281
334
  {
282
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
335
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
283
336
    return(true);
284
337
  }
285
338
 
287
340
 
288
341
  if (!drop_temporary)
289
342
  {
290
 
    if (!thd->locked_tables &&
291
 
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
343
    if (!session->locked_tables &&
 
344
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
292
345
      return(true);
293
346
  }
294
347
 
297
350
    LOCK_open during wait_if_global_read_lock(), other threads could not
298
351
    close their tables. This would make a pretty deadlock.
299
352
  */
300
 
  error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
 
353
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0);
301
354
 
302
355
  if (need_start_waiting)
303
 
    start_waiting_global_read_lock(thd);
 
356
    start_waiting_global_read_lock(session);
304
357
 
305
358
  if (error)
306
359
    return(true);
307
 
  my_ok(thd);
 
360
  session->my_ok();
308
361
  return(false);
309
362
}
310
363
 
313
366
 
314
367
  SYNOPSIS
315
368
    mysql_rm_table_part2()
316
 
    thd                 Thread handler
 
369
    session                     Thread handler
317
370
    tables              Tables to drop
318
371
    if_exists           If set, don't give an error if table doesn't exists.
319
372
                        In this case we give an warning of level 'NOTE'
320
373
    drop_temporary      Only drop temporary tables
321
374
    drop_view           Allow to delete VIEW .frm
322
375
    dont_log_query      Don't write query to log files. This will also not
323
 
                        generate warnings if the handler files doesn't exists  
 
376
                        generate warnings if the handler files doesn't exists
324
377
 
325
378
  TODO:
326
379
    When logging to the binary log, we should log
338
391
   -1   Thread was killed
339
392
*/
340
393
 
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)
 
394
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
 
395
                         bool drop_temporary, bool dont_log_query)
344
396
{
345
397
  TableList *table;
346
398
  char path[FN_REFLEN], *alias;
347
 
  uint32_t path_length;
 
399
  uint32_t path_length= 0;
348
400
  String wrong_tables;
349
401
  int error= 0;
350
402
  int non_temp_tables_count= 0;
351
403
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
352
404
  String built_query;
353
405
 
354
 
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
406
  if (!dont_log_query)
355
407
  {
356
408
    built_query.set_charset(system_charset_info);
357
409
    if (if_exists)
360
412
      built_query.append("DROP Table ");
361
413
  }
362
414
 
363
 
  mysql_ha_rm_tables(thd, tables, false);
364
 
 
365
415
  pthread_mutex_lock(&LOCK_open);
366
416
 
367
417
  /*
378
428
      table->db_type= share->db_type();
379
429
  }
380
430
 
381
 
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
 
431
  if (!drop_temporary && lock_table_names_exclusively(session, tables))
382
432
  {
383
433
    pthread_mutex_unlock(&LOCK_open);
384
434
    return(1);
385
435
  }
386
436
 
387
437
  /* Don't give warnings for not found errors, as we already generate notes */
388
 
  thd->no_warnings_for_error= 1;
 
438
  session->no_warnings_for_error= 1;
389
439
 
390
440
  for (table= tables; table; table= table->next_local)
391
441
  {
392
442
    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);
 
443
    StorageEngine *table_type;
 
444
 
 
445
    error= drop_temporary_table(session, table);
398
446
 
399
447
    switch (error) {
400
448
    case  0:
402
450
      tmp_table_deleted= 1;
403
451
      continue;
404
452
    case -1:
405
 
      assert(thd->in_sub_stmt);
406
453
      error= 1;
407
454
      goto err_with_placeholders;
408
455
    default:
416
463
      being built.  The string always end in a comma and the comma
417
464
      will be chopped off before being written to the binary log.
418
465
      */
419
 
    if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
466
    if (!dont_log_query)
420
467
    {
421
468
      non_temp_tables_count++;
422
469
      /*
423
470
        Don't write the database name if it is the current one (or if
424
 
        thd->db is NULL).
 
471
        session->db is NULL).
425
472
      */
426
473
      built_query.append("`");
427
 
      if (thd->db == NULL || strcmp(db,thd->db) != 0)
 
474
      if (session->db == NULL || strcmp(db,session->db) != 0)
428
475
      {
429
476
        built_query.append(db);
430
477
        built_query.append("`.`");
438
485
    if (!drop_temporary)
439
486
    {
440
487
      Table *locked_table;
441
 
      abort_locked_tables(thd, db, table->table_name);
442
 
      remove_table_from_cache(thd, db, table->table_name,
 
488
      abort_locked_tables(session, db, table->table_name);
 
489
      remove_table_from_cache(session, db, table->table_name,
443
490
                              RTFC_WAIT_OTHER_THREAD_FLAG |
444
491
                              RTFC_CHECK_KILLED_FLAG);
445
492
      /*
446
493
        If the table was used in lock tables, remember it so that
447
494
        unlock_table_names can free it
448
495
      */
449
 
      if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
 
496
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
450
497
        table->table= locked_table;
451
498
 
452
 
      if (thd->killed)
 
499
      if (session->killed)
453
500
      {
454
501
        error= -1;
455
502
        goto err_with_placeholders;
456
503
      }
457
504
      alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
458
505
      /* remove .frm file and engine files */
459
 
      path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
 
506
      path_length= build_table_filename(path, sizeof(path), db, alias, "",
460
507
                                        table->internal_tmp_table ?
461
508
                                        FN_IS_TMP : 0);
462
509
    }
463
510
    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)))
 
511
        ((table_type == NULL && (table_proto_exists(path)!=EEXIST))))
466
512
    {
467
513
      // Table was not found on disk and table can't be created from engine
468
514
      if (if_exists)
469
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
515
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
470
516
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
471
517
                            table->table_name);
472
518
      else
474
520
    }
475
521
    else
476
522
    {
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,
 
523
      error= ha_delete_table(session, path, db, table->table_name,
486
524
                             !dont_log_query);
487
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
488
 
          (if_exists || table_type == NULL))
 
525
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
 
526
          if_exists)
489
527
      {
490
528
        error= 0;
491
 
        thd->clear_error();
 
529
        session->clear_error();
492
530
      }
493
531
      if (error == HA_ERR_ROW_IS_REFERENCED)
494
532
      {
498
536
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
499
537
      {
500
538
        int new_error;
501
 
        /* Delete the table definition file */
502
 
        my_stpcpy(end,reg_ext);
503
 
        if (!(new_error=my_delete(path,MYF(MY_WME))))
 
539
 
 
540
        if (!(new_error= delete_table_proto_file(path)))
504
541
        {
505
542
          some_tables_deleted=1;
506
543
          new_error= 0;
520
557
    on the table name.
521
558
  */
522
559
  pthread_mutex_unlock(&LOCK_open);
523
 
  thd->thread_specific_used|= tmp_table_deleted;
 
560
  session->thread_specific_used|= tmp_table_deleted;
524
561
  error= 0;
525
562
  if (wrong_tables.length())
526
563
  {
538
575
  {
539
576
    if (!dont_log_query)
540
577
    {
541
 
      if (!thd->current_stmt_binlog_row_based ||
542
 
          (non_temp_tables_count > 0 && !tmp_table_deleted))
 
578
      if ((non_temp_tables_count > 0 && !tmp_table_deleted))
543
579
      {
544
580
        /*
545
581
          In this case, we are either using statement-based
548
584
          tables).  In this case, we can write the original query into
549
585
          the binary log.
550
586
         */
551
 
        write_bin_log(thd, !error, thd->query, thd->query_length);
 
587
        write_bin_log(session, !error, session->query, session->query_length);
552
588
      }
553
 
      else if (thd->current_stmt_binlog_row_based &&
554
 
               non_temp_tables_count > 0 &&
 
589
      else if (non_temp_tables_count > 0 &&
555
590
               tmp_table_deleted)
556
591
      {
557
592
        /*
568
603
        */
569
604
        built_query.chop();                  // Chop of the last comma
570
605
        built_query.append(" /* generated by server */");
571
 
        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
 
606
        write_bin_log(session, !error, built_query.ptr(), built_query.length());
572
607
      }
573
608
      /*
574
609
        The remaining cases are:
582
617
  }
583
618
  pthread_mutex_lock(&LOCK_open);
584
619
err_with_placeholders:
585
 
  unlock_table_names(thd, tables, (TableList*) 0);
 
620
  unlock_table_names(session, tables, (TableList*) 0);
586
621
  pthread_mutex_unlock(&LOCK_open);
587
 
  thd->no_warnings_for_error= 0;
 
622
  session->no_warnings_for_error= 0;
588
623
  return(error);
589
624
}
590
625
 
594
629
 
595
630
  SYNOPSIS
596
631
    quick_rm_table()
597
 
      base                      The handlerton handle.
 
632
      base                      The StorageEngine handle.
598
633
      db                        The database name.
599
634
      table_name                The table name.
600
635
      flags                     flags for build_table_filename().
604
639
    != 0        Error
605
640
*/
606
641
 
607
 
bool quick_rm_table(handlerton *base,const char *db,
 
642
bool quick_rm_table(StorageEngine *,const char *db,
608
643
                    const char *table_name, uint32_t flags)
609
644
{
610
645
  char path[FN_REFLEN];
611
646
  bool error= 0;
612
647
 
613
 
  uint32_t 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) ||
 
648
  build_table_filename(path, sizeof(path), db, table_name, "", flags);
 
649
 
 
650
  error= delete_table_proto_file(path);
 
651
 
 
652
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
619
653
              error);
620
654
}
621
655
 
635
669
static int sort_keys(KEY *a, KEY *b)
636
670
{
637
671
  ulong a_flags= a->flags, b_flags= b->flags;
638
 
  
 
672
 
639
673
  if (a_flags & HA_NOSAME)
640
674
  {
641
675
    if (!(b_flags & HA_NOSAME))
645
679
      /* Sort NOT NULL keys before other keys */
646
680
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
647
681
    }
648
 
    if (a->name == primary_key_name)
 
682
    if (is_primary_key(a))
649
683
      return -1;
650
 
    if (b->name == primary_key_name)
 
684
    if (is_primary_key(b))
651
685
      return 1;
652
686
    /* Sort keys don't containing partial segments before others */
653
687
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
691
725
  TYPELIB tmp= *typelib;
692
726
  const char **cur_value= typelib->type_names;
693
727
  unsigned int *cur_length= typelib->type_lengths;
694
 
  *dup_val_count= 0;  
695
 
  
 
728
  *dup_val_count= 0;
 
729
 
696
730
  for ( ; tmp.count > 1; cur_value++, cur_length++)
697
731
  {
698
732
    tmp.type_names++;
762
796
   1    Error
763
797
*/
764
798
 
765
 
int prepare_create_field(Create_field *sql_field, 
 
799
int prepare_create_field(Create_field *sql_field,
766
800
                         uint32_t *blob_columns,
767
801
                         int *timestamps, int *timestamps_with_niladic,
768
 
                         int64_t table_flags __attribute__((unused)))
 
802
                         int64_t )
769
803
{
770
804
  unsigned int dup_val_count;
771
805
 
783
817
    if (sql_field->charset->state & MY_CS_BINSORT)
784
818
      sql_field->pack_flag|=FIELDFLAG_BINARY;
785
819
    sql_field->length=8;                        // Unireg field length
786
 
    sql_field->unireg_check=Field::BLOB_FIELD;
787
820
    (*blob_columns)++;
788
821
    break;
789
822
  case DRIZZLE_TYPE_VARCHAR:
796
829
      FIELDFLAG_INTERVAL;
797
830
    if (sql_field->charset->state & MY_CS_BINSORT)
798
831
      sql_field->pack_flag|=FIELDFLAG_BINARY;
799
 
    sql_field->unireg_check=Field::INTERVAL_FIELD;
800
832
    if (check_duplicates_in_interval("ENUM",sql_field->field_name,
801
833
                                 sql_field->interval,
802
834
                                     sql_field->charset, &dup_val_count))
803
835
      return(1);
804
836
    break;
805
 
  case DRIZZLE_TYPE_NEWDATE:  // Rest of string types
806
 
  case DRIZZLE_TYPE_TIME:
 
837
  case DRIZZLE_TYPE_DATE:  // Rest of string types
807
838
  case DRIZZLE_TYPE_DATETIME:
808
839
  case DRIZZLE_TYPE_NULL:
809
 
    sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
 
840
    sql_field->pack_flag=f_settype((uint32_t) sql_field->sql_type);
810
841
    break;
811
842
  case DRIZZLE_TYPE_NEWDECIMAL:
812
843
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
836
867
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
837
868
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
838
869
                           FIELDFLAG_DECIMAL) |
839
 
                          f_settype((uint) sql_field->sql_type) |
 
870
                          f_settype((uint32_t) sql_field->sql_type) |
840
871
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
841
872
    break;
842
873
  }
843
 
  if (!(sql_field->flags & NOT_NULL_FLAG))
 
874
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
 
875
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
844
876
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
845
877
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
846
878
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
852
884
 
853
885
  SYNOPSIS
854
886
    mysql_prepare_create_table()
855
 
      thd                       Thread object.
 
887
      session                       Thread object.
856
888
      create_info               Create information (like MAX_ROWS).
857
889
      alter_info                List of columns and indexes to create
858
890
      tmp_table                 If a temporary table is to be created.
874
906
*/
875
907
 
876
908
static int
877
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
909
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
878
910
                           Alter_info *alter_info,
879
911
                           bool tmp_table,
880
912
                               uint32_t *db_options,
922
954
 
923
955
    save_cs= sql_field->charset;
924
956
    if ((sql_field->flags & BINCMP_FLAG) &&
925
 
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
926
 
                                                    MY_CS_BINSORT,MYF(0))))
 
957
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, MY_CS_BINSORT)))
927
958
    {
928
959
      char tmp[64];
929
 
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
930
 
              STRING_WITH_LEN("_bin"));
 
960
      char *tmp_pos= tmp;
 
961
      strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
 
962
      tmp_pos+= strlen(tmp);
 
963
      strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
931
964
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
932
965
      return(true);
933
966
    }
936
969
      Convert the default value from client character
937
970
      set into the column character set if necessary.
938
971
    */
939
 
    if (sql_field->def && 
 
972
    if (sql_field->def &&
940
973
        save_cs != sql_field->def->collation.collation &&
941
974
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
942
975
    {
978
1011
          occupied memory at the same time when we free this
979
1012
          sql_field -- at the end of execution.
980
1013
        */
981
 
        interval= sql_field->interval= typelib(thd->mem_root,
 
1014
        interval= sql_field->interval= typelib(session->mem_root,
982
1015
                                               sql_field->interval_list);
983
1016
        List_iterator<String> int_it(sql_field->interval_list);
984
1017
        String conv, *tmp;
985
1018
        char comma_buf[4];
986
1019
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
987
 
                                          (unsigned char*) comma_buf + 
 
1020
                                          (unsigned char*) comma_buf +
988
1021
                                          sizeof(comma_buf));
989
1022
        assert(comma_length > 0);
990
1023
        for (uint32_t i= 0; (tmp= int_it++); i++)
995
1028
          {
996
1029
            uint32_t cnv_errs;
997
1030
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
998
 
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
 
1031
            interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
999
1032
                                                  conv.length());
1000
1033
            interval->type_lengths[i]= conv.length();
1001
1034
          }
1025
1058
            }
1026
1059
 
1027
1060
            /* else, the defaults yield the correct length for NULLs. */
1028
 
          } 
 
1061
          }
1029
1062
          else /* not NULL */
1030
1063
          {
1031
1064
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
1039
1072
        calculate_interval_lengths(cs, interval, &field_length, &dummy);
1040
1073
        sql_field->length= field_length;
1041
1074
      }
1042
 
      set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
 
1075
      set_if_smaller(sql_field->length, (uint32_t)MAX_FIELD_WIDTH-1);
1043
1076
    }
1044
1077
 
1045
1078
    sql_field->create_length_to_internal_length();
1046
 
    if (prepare_blob_field(thd, sql_field))
 
1079
    if (prepare_blob_field(session, sql_field))
1047
1080
      return(true);
1048
1081
 
1049
1082
    if (!(sql_field->flags & NOT_NULL_FLAG))
1085
1118
          sql_field->decimals=          dup_field->decimals;
1086
1119
          sql_field->create_length_to_internal_length();
1087
1120
          sql_field->unireg_check=      dup_field->unireg_check;
1088
 
          /* 
 
1121
          /*
1089
1122
            We're making one field from two, the result field will have
1090
1123
            dup_field->flags as flags. If we've incremented null_fields
1091
1124
            because of sql_field->flags, decrement it back.
1094
1127
            null_fields--;
1095
1128
          sql_field->flags=             dup_field->flags;
1096
1129
          sql_field->interval=          dup_field->interval;
 
1130
          sql_field->vcol_info=         dup_field->vcol_info;
 
1131
          sql_field->is_stored=      dup_field->is_stored;
1097
1132
          it2.remove();                 // Remove first (create) definition
1098
1133
          select_field_pos--;
1099
1134
          break;
1116
1151
  {
1117
1152
    assert(sql_field->charset != 0);
1118
1153
 
1119
 
    if (prepare_create_field(sql_field, &blob_columns, 
 
1154
    if (prepare_create_field(sql_field, &blob_columns,
1120
1155
                             &timestamps, &timestamps_with_niladic,
1121
1156
                             file->ha_table_flags()))
1122
1157
      return(true);
1125
1160
    sql_field->offset= record_offset;
1126
1161
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1127
1162
      auto_increment++;
1128
 
    record_offset+= sql_field->pack_length;
 
1163
    /*
 
1164
          For now skip fields that are not physically stored in the database
 
1165
          (virtual fields) and update their offset later
 
1166
          (see the next loop).
 
1167
        */
 
1168
    if (sql_field->is_stored)
 
1169
      record_offset+= sql_field->pack_length;
 
1170
  }
 
1171
  /* Update virtual fields' offset */
 
1172
  it.rewind();
 
1173
  while ((sql_field=it++))
 
1174
  {
 
1175
    if (not sql_field->is_stored)
 
1176
    {
 
1177
      sql_field->offset= record_offset;
 
1178
      record_offset+= sql_field->pack_length;
 
1179
    }
1129
1180
  }
1130
1181
  if (timestamps_with_niladic > 1)
1131
1182
  {
1172
1223
    if (key->type == Key::FOREIGN_KEY)
1173
1224
    {
1174
1225
      fk_key_count++;
 
1226
      if (((Foreign_key *)key)->validate(alter_info->create_list))
 
1227
        return true;
1175
1228
      Foreign_key *fk_key= (Foreign_key*) key;
1176
1229
      if (fk_key->ref_columns.elements &&
1177
1230
          fk_key->ref_columns.elements != fk_key->columns.elements)
1228
1281
    else
1229
1282
      (*key_count)--;
1230
1283
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
1231
 
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
 
1284
        is_primary_key_name(key->name.str))
1232
1285
    {
1233
1286
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1234
1287
      return(true);
1304
1357
    {
1305
1358
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
1306
1359
               key->key_create_info.comment.str,"INDEX COMMENT",
1307
 
               (uint) INDEX_COMMENT_MAXLEN);
 
1360
               (uint32_t) INDEX_COMMENT_MAXLEN);
1308
1361
      return(-1);
1309
1362
    }
1310
1363
 
1361
1414
            return(true);
1362
1415
          }
1363
1416
        }
 
1417
        if (not sql_field->is_stored)
 
1418
        {
 
1419
          /* Key fields must always be physically stored. */
 
1420
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
 
1421
          return(true);
 
1422
        }
 
1423
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
 
1424
        {
 
1425
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
 
1426
          return(true);
 
1427
        }
1364
1428
        if (!(sql_field->flags & NOT_NULL_FLAG))
1365
1429
        {
1366
1430
          if (key->type == Key::PRIMARY)
1406
1470
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
1407
1471
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1408
1472
                       length);
1409
 
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1473
              push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1410
1474
                           ER_TOO_LONG_KEY, warn_buff);
1411
1475
              /* Align key length to multibyte char boundary */
1412
1476
              length-= length % sql_field->charset->mbmaxlen;
1445
1509
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1446
1510
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1447
1511
                   length);
1448
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1512
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1449
1513
                       ER_TOO_LONG_KEY, warn_buff);
1450
1514
          /* Align key length to multibyte char boundary */
1451
1515
          length-= length % sql_field->charset->mbmaxlen;
1487
1551
                       MYF(0));
1488
1552
            return(true);
1489
1553
          }
1490
 
          key_name=primary_key_name;
 
1554
          static const char pkey_name[]= "PRIMARY";
 
1555
          key_name=pkey_name;
1491
1556
          primary_key=1;
1492
1557
        }
1493
1558
        else if (!(key_name= key->name.str))
1538
1603
  {
1539
1604
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1540
1605
 
1541
 
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
 
1606
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1542
1607
        !sql_field->def &&
1543
1608
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1544
1609
        (sql_field->flags & NOT_NULL_FLAG) &&
1566
1631
  return(false);
1567
1632
}
1568
1633
 
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
 
 
1602
1634
/*
1603
1635
  Extend long VARCHAR fields to blob & prepare field if it's a blob
1604
1636
 
1612
1644
        In this case the error is given
1613
1645
*/
1614
1646
 
1615
 
static bool prepare_blob_field(THD *thd __attribute__((unused)),
 
1647
static bool prepare_blob_field(Session *,
1616
1648
                               Create_field *sql_field)
1617
1649
{
1618
1650
 
1623
1655
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1624
1656
    return(1);
1625
1657
  }
1626
 
    
 
1658
 
1627
1659
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1628
1660
  {
1629
1661
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1639
1671
 
1640
1672
 
1641
1673
/*
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)
1657
 
{
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);
1675
 
}
1676
 
 
1677
 
 
1678
 
/*
1679
1674
  Create a table
1680
1675
 
1681
1676
  SYNOPSIS
1682
1677
    mysql_create_table_no_lock()
1683
 
    thd                 Thread object
 
1678
    session                     Thread object
1684
1679
    db                  Database
1685
1680
    table_name          Table name
1686
1681
    create_info         Create information (like MAX_ROWS)
1688
1683
    keys                List of keys to create
1689
1684
    internal_tmp_table  Set to 1 if this is an internal temporary table
1690
1685
                        (From ALTER Table)
1691
 
    select_field_count  
 
1686
    select_field_count
1692
1687
 
1693
1688
  DESCRIPTION
1694
1689
    If one creates a temporary table, this is automatically opened
1708
1703
    true  error
1709
1704
*/
1710
1705
 
1711
 
bool mysql_create_table_no_lock(THD *thd,
 
1706
bool mysql_create_table_no_lock(Session *session,
1712
1707
                                const char *db, const char *table_name,
1713
1708
                                HA_CREATE_INFO *create_info,
1714
1709
                                Alter_info *alter_info,
1715
1710
                                bool internal_tmp_table,
1716
 
                                uint32_t select_field_count)
 
1711
                                uint32_t select_field_count,
 
1712
                                bool lock_open_lock)
1717
1713
{
1718
1714
  char          path[FN_REFLEN];
1719
1715
  uint32_t          path_length;
1729
1725
               MYF(0));
1730
1726
    return(true);
1731
1727
  }
1732
 
  if (check_engine(thd, table_name, create_info))
 
1728
  if (check_engine(session, table_name, create_info))
1733
1729
    return(true);
1734
1730
  db_options= create_info->table_options;
1735
1731
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1736
1732
    db_options|=HA_OPTION_PACK_RECORD;
1737
1733
  alias= table_case_name(create_info, table_name);
1738
 
  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
 
1734
  if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1739
1735
                              create_info->db_type)))
1740
1736
  {
1741
1737
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1742
1738
    return(true);
1743
1739
  }
1744
1740
 
1745
 
  set_table_default_charset(thd, create_info, (char*) db);
 
1741
  set_table_default_charset(session, create_info, (char*) db);
1746
1742
 
1747
 
  if (mysql_prepare_create_table(thd, create_info, alter_info,
 
1743
  if (mysql_prepare_create_table(session, create_info, alter_info,
1748
1744
                                 internal_tmp_table,
1749
1745
                                 &db_options, file,
1750
1746
                          &key_info_buffer, &key_count,
1754
1750
      /* Check if table exists */
1755
1751
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1756
1752
  {
1757
 
    path_length= build_tmptable_filename(thd, path, sizeof(path));
 
1753
    path_length= build_tmptable_filename(session, path, sizeof(path));
1758
1754
    create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1759
1755
  }
1760
 
  else  
 
1756
  else
1761
1757
  {
1762
1758
 #ifdef FN_DEVCHAR
1763
1759
    /* check if the table name contains FN_DEVCHAR when defined */
1767
1763
      return(true);
1768
1764
    }
1769
1765
#endif
1770
 
    path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
 
1766
    path_length= build_table_filename(path, sizeof(path), db, alias, "",
1771
1767
                                      internal_tmp_table ? FN_IS_TMP : 0);
1772
1768
  }
1773
1769
 
1774
1770
  /* Check if table already exists */
1775
1771
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1776
 
      find_temporary_table(thd, db, table_name))
 
1772
      find_temporary_table(session, db, table_name))
1777
1773
  {
1778
1774
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1779
1775
    {
1780
1776
      create_info->table_existed= 1;            // Mark that table existed
1781
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1777
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1782
1778
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1783
1779
                          alias);
1784
1780
      error= 0;
1788
1784
    goto err;
1789
1785
  }
1790
1786
 
1791
 
  pthread_mutex_lock(&LOCK_open);
 
1787
  if (lock_open_lock)
 
1788
    pthread_mutex_lock(&LOCK_open);
1792
1789
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1793
1790
  {
1794
 
    if (!access(path,F_OK))
 
1791
    if (table_proto_exists(path)==EEXIST)
1795
1792
    {
1796
1793
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1797
1794
        goto warn;
1826
1823
  {
1827
1824
    bool create_if_not_exists =
1828
1825
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1829
 
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
 
1826
    int retcode = ha_table_exists_in_engine(session, db, table_name);
1830
1827
    switch (retcode)
1831
1828
    {
1832
1829
      case HA_ERR_NO_SUCH_TABLE:
1834
1831
        break;
1835
1832
      case HA_ERR_TABLE_EXIST:
1836
1833
 
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;
 
1834
        if (create_if_not_exists)
 
1835
          goto warn;
 
1836
        my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
 
1837
        goto unlock_and_end;
1842
1838
      default:
1843
1839
        my_error(retcode, MYF(0),table_name);
1844
1840
        goto unlock_and_end;
1845
1841
    }
1846
1842
  }
1847
1843
 
1848
 
  thd_proc_info(thd, "creating table");
 
1844
  session->set_proc_info("creating table");
1849
1845
  create_info->table_existed= 0;                // Mark that table is created
1850
1846
 
1851
1847
#ifdef HAVE_READLINK
1864
1860
#endif /* HAVE_READLINK */
1865
1861
  {
1866
1862
    if (create_info->data_file_name)
1867
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1863
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1868
1864
                   "DATA DIRECTORY option ignored");
1869
1865
    if (create_info->index_file_name)
1870
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1866
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1871
1867
                   "INDEX DIRECTORY option ignored");
1872
1868
    create_info->data_file_name= create_info->index_file_name= 0;
1873
1869
  }
1874
1870
  create_info->table_options=db_options;
1875
1871
 
1876
 
  path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1877
 
  if (rea_create_table(thd, path, db, table_name,
 
1872
  if (rea_create_table(session, path, db, table_name,
1878
1873
                       create_info, alter_info->create_list,
1879
 
                       key_count, key_info_buffer, file))
 
1874
                       key_count, key_info_buffer, file, false))
1880
1875
    goto unlock_and_end;
1881
1876
 
1882
1877
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1883
1878
  {
1884
1879
    /* Open table and put in temporary table list */
1885
 
    if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
 
1880
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1886
1881
    {
1887
 
      (void) rm_temporary_table(create_info->db_type, path, false);
 
1882
      (void) rm_temporary_table(create_info->db_type, path);
1888
1883
      goto unlock_and_end;
1889
1884
    }
1890
 
    thd->thread_specific_used= true;
 
1885
    session->thread_specific_used= true;
1891
1886
  }
1892
1887
 
1893
1888
  /*
1898
1893
    Otherwise, the statement shall be binlogged.
1899
1894
   */
1900
1895
  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);
 
1896
      ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
 
1897
    write_bin_log(session, true, session->query, session->query_length);
1905
1898
  error= false;
1906
1899
unlock_and_end:
1907
 
  pthread_mutex_unlock(&LOCK_open);
 
1900
  if (lock_open_lock)
 
1901
    pthread_mutex_unlock(&LOCK_open);
1908
1902
 
1909
1903
err:
1910
 
  thd_proc_info(thd, "After create");
 
1904
  session->set_proc_info("After create");
1911
1905
  delete file;
1912
1906
  return(error);
1913
1907
 
1914
1908
warn:
1915
1909
  error= false;
1916
 
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1910
  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1917
1911
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1918
1912
                      alias);
1919
1913
  create_info->table_existed= 1;                // Mark that table existed
1925
1919
  Database locking aware wrapper for mysql_create_table_no_lock(),
1926
1920
*/
1927
1921
 
1928
 
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
 
1922
bool mysql_create_table(Session *session, const char *db, const char *table_name,
1929
1923
                        HA_CREATE_INFO *create_info,
1930
1924
                        Alter_info *alter_info,
1931
1925
                        bool internal_tmp_table,
1936
1930
 
1937
1931
  /* Wait for any database locks */
1938
1932
  pthread_mutex_lock(&LOCK_lock_db);
1939
 
  while (!thd->killed &&
 
1933
  while (!session->killed &&
1940
1934
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
1941
1935
  {
1942
 
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1936
    wait_for_condition(session, &LOCK_lock_db, &COND_refresh);
1943
1937
    pthread_mutex_lock(&LOCK_lock_db);
1944
1938
  }
1945
1939
 
1946
 
  if (thd->killed)
 
1940
  if (session->killed)
1947
1941
  {
1948
1942
    pthread_mutex_unlock(&LOCK_lock_db);
1949
1943
    return(true);
1953
1947
 
1954
1948
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1955
1949
  {
1956
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
1950
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
1957
1951
    {
1958
1952
      result= true;
1959
1953
      goto unlock;
1962
1956
    {
1963
1957
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1964
1958
      {
1965
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1959
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1966
1960
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1967
1961
                            table_name);
1968
1962
        create_info->table_existed= 1;
1977
1971
    }
1978
1972
  }
1979
1973
 
1980
 
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
 
1974
  result= mysql_create_table_no_lock(session, db, table_name, create_info,
1981
1975
                                     alter_info,
1982
1976
                                     internal_tmp_table,
1983
 
                                     select_field_count);
 
1977
                                     select_field_count, true);
1984
1978
 
1985
1979
unlock:
1986
1980
  if (name_lock)
1987
1981
  {
1988
1982
    pthread_mutex_lock(&LOCK_open);
1989
 
    unlink_open_table(thd, name_lock, false);
 
1983
    unlink_open_table(session, name_lock, false);
1990
1984
    pthread_mutex_unlock(&LOCK_open);
1991
1985
  }
1992
1986
  pthread_mutex_lock(&LOCK_lock_db);
2017
2011
  char buff[MAX_FIELD_NAME],*buff_end;
2018
2012
 
2019
2013
  if (!check_if_keyname_exists(field_name,start,end) &&
2020
 
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
 
2014
      !is_primary_key_name(field_name))
2021
2015
    return (char*) field_name;                  // Use fieldname
2022
 
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
 
2016
 
 
2017
  buff_end= strncpy(buff, field_name, sizeof(buff)-4);
 
2018
  buff_end+= strlen(buff);
2023
2019
 
2024
2020
  /*
2025
2021
    Only 3 chars + '\0' left, so need to limit to 2 digit
2046
2042
 
2047
2043
  SYNOPSIS
2048
2044
    mysql_rename_table()
2049
 
      base                      The handlerton handle.
 
2045
      base                      The StorageEngine handle.
2050
2046
      old_db                    The old database name.
2051
2047
      old_name                  The old table name.
2052
2048
      new_db                    The new database name.
2063
2059
*/
2064
2060
 
2065
2061
bool
2066
 
mysql_rename_table(handlerton *base, const char *old_db,
 
2062
mysql_rename_table(StorageEngine *base, const char *old_db,
2067
2063
                   const char *old_name, const char *new_db,
2068
2064
                   const char *new_name, uint32_t flags)
2069
2065
{
2070
 
  THD *thd= current_thd;
 
2066
  Session *session= current_session;
2071
2067
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2072
2068
  char *from_base= from, *to_base= to;
2073
2069
  char tmp_name[NAME_LEN+1];
2075
2071
  int error=0;
2076
2072
 
2077
2073
  file= (base == NULL ? 0 :
2078
 
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
 
2074
         get_new_handler((TABLE_SHARE*) 0, session->mem_root, base));
2079
2075
 
2080
2076
  build_table_filename(from, sizeof(from), old_db, old_name, "",
2081
2077
                       flags & FN_FROM_IS_TMP);
2090
2086
  if (lower_case_table_names == 2 && file &&
2091
2087
      !(file->ha_table_flags() & HA_FILE_BASED))
2092
2088
  {
2093
 
    my_stpcpy(tmp_name, old_name);
 
2089
    strcpy(tmp_name, old_name);
2094
2090
    my_casedn_str(files_charset_info, tmp_name);
2095
2091
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2096
2092
                         flags & FN_FROM_IS_TMP);
2097
2093
    from_base= lc_from;
2098
2094
 
2099
 
    my_stpcpy(tmp_name, new_name);
 
2095
    strcpy(tmp_name, new_name);
2100
2096
    my_casedn_str(files_charset_info, tmp_name);
2101
2097
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2102
2098
                         flags & FN_TO_IS_TMP);
2104
2100
  }
2105
2101
  if (!file || !(error=file->ha_rename_table(from_base, to_base)))
2106
2102
  {
2107
 
    if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
 
2103
    if(!(flags & NO_FRM_RENAME)
 
2104
       && rename_table_proto_file(from_base, to_base))
2108
2105
    {
2109
 
      error=my_errno;
2110
 
      /* Restore old file name */
 
2106
      error= my_errno;
2111
2107
      if (file)
2112
2108
        file->ha_rename_table(to_base, from_base);
2113
2109
    }
2126
2122
 
2127
2123
  SYNOPSIS
2128
2124
    wait_while_table_is_used()
2129
 
    thd                 Thread handler
 
2125
    session                     Thread handler
2130
2126
    table               Table to remove from cache
2131
2127
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2132
2128
                        HA_EXTRA_FORCE_REOPEN if table is not be used
2140
2136
    Win32 clients must also have a WRITE LOCK on the table !
2141
2137
*/
2142
2138
 
2143
 
void wait_while_table_is_used(THD *thd, Table *table,
 
2139
void wait_while_table_is_used(Session *session, Table *table,
2144
2140
                              enum ha_extra_function function)
2145
2141
{
2146
2142
 
2148
2144
 
2149
2145
  table->file->extra(function);
2150
2146
  /* Mark all tables that are in use as 'old' */
2151
 
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
 
2147
  mysql_lock_abort(session, table, true);       /* end threads waiting on lock */
2152
2148
 
2153
2149
  /* Wait until all there are no other threads that has this table open */
2154
 
  remove_table_from_cache(thd, table->s->db.str,
 
2150
  remove_table_from_cache(session, table->s->db.str,
2155
2151
                          table->s->table_name.str,
2156
2152
                          RTFC_WAIT_OTHER_THREAD_FLAG);
2157
2153
  return;
2162
2158
 
2163
2159
  SYNOPSIS
2164
2160
    close_cached_table()
2165
 
    thd                 Thread handler
 
2161
    session                     Thread handler
2166
2162
    table               Table to remove from cache
2167
2163
 
2168
2164
  NOTES
2174
2170
    Win32 clients must also have a WRITE LOCK on the table !
2175
2171
*/
2176
2172
 
2177
 
void close_cached_table(THD *thd, Table *table)
 
2173
void close_cached_table(Session *session, Table *table)
2178
2174
{
2179
2175
 
2180
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
2176
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2181
2177
  /* Close lock if this is not got with LOCK TABLES */
2182
 
  if (thd->lock)
 
2178
  if (session->lock)
2183
2179
  {
2184
 
    mysql_unlock_tables(thd, thd->lock);
2185
 
    thd->lock=0;                        // Start locked threads
 
2180
    mysql_unlock_tables(session, session->lock);
 
2181
    session->lock=0;                    // Start locked threads
2186
2182
  }
2187
2183
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
2188
 
  unlink_open_table(thd, table, true);
 
2184
  unlink_open_table(session, table, true);
2189
2185
 
2190
2186
  /* When lock on LOCK_open is freed other threads can continue */
2191
2187
  broadcast_refresh();
2192
2188
  return;
2193
2189
}
2194
2190
 
2195
 
static int send_check_errmsg(THD *thd, TableList* table,
 
2191
static int send_check_errmsg(Session *session, TableList* table,
2196
2192
                             const char* operator_name, const char* errmsg)
2197
2193
 
2198
2194
{
2199
 
  Protocol *protocol= thd->protocol;
 
2195
  Protocol *protocol= session->protocol;
2200
2196
  protocol->prepare_for_resend();
2201
2197
  protocol->store(table->alias, system_charset_info);
2202
2198
  protocol->store((char*) operator_name, system_charset_info);
2203
2199
  protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2204
2200
  protocol->store(errmsg, system_charset_info);
2205
 
  thd->clear_error();
 
2201
  session->clear_error();
2206
2202
  if (protocol->write())
2207
2203
    return -1;
2208
2204
  return 1;
2209
2205
}
2210
2206
 
2211
2207
 
2212
 
static int prepare_for_repair(THD *thd, TableList *table_list,
 
2208
static int prepare_for_repair(Session *session, TableList *table_list,
2213
2209
                              HA_CHECK_OPT *check_opt)
2214
2210
{
2215
2211
  int error= 0;
2219
2215
  const char **ext;
2220
2216
  struct stat stat_info;
2221
2217
 
2222
 
  if (!(check_opt->sql_flags & TT_USEFRM))
 
2218
  if (!(check_opt->use_frm))
2223
2219
    return(0);
2224
2220
 
2225
2221
  if (!(table= table_list->table))              /* if open_ltable failed */
2227
2223
    char key[MAX_DBKEY_LENGTH];
2228
2224
    uint32_t key_length;
2229
2225
 
2230
 
    key_length= create_table_def_key(thd, key, table_list, 0);
 
2226
    key_length= create_table_def_key(session, key, table_list, 0);
2231
2227
    pthread_mutex_lock(&LOCK_open);
2232
 
    if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
 
2228
    if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2233
2229
                                  &error))))
2234
2230
    {
2235
2231
      pthread_mutex_unlock(&LOCK_open);
2236
2232
      return(0);                                // Can't open frm file
2237
2233
    }
2238
2234
 
2239
 
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
 
2235
    if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2240
2236
    {
2241
2237
      release_table_share(share, RELEASE_NORMAL);
2242
2238
      pthread_mutex_unlock(&LOCK_open);
2251
2247
  */
2252
2248
  if (table->s->tmp_table)
2253
2249
  {
2254
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2250
    error= send_check_errmsg(session, table_list, "repair",
2255
2251
                             "Cannot repair temporary table from .frm file");
2256
2252
    goto end;
2257
2253
  }
2270
2266
    Check if this is a table type that stores index and data separately,
2271
2267
    like ISAM or MyISAM. We assume fixed order of engine file name
2272
2268
    extentions array. First element of engine file name extentions array
2273
 
    is meta/index file extention. Second element - data file extention. 
 
2269
    is meta/index file extention. Second element - data file extention.
2274
2270
  */
2275
2271
  ext= table->file->bas_ext();
2276
2272
  if (!ext[0] || !ext[1])
2277
2273
    goto end;                                   // No data file
2278
2274
 
2279
2275
  // Name of data file
2280
 
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
 
2276
  sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2281
2277
  if (stat(from, &stat_info))
2282
2278
    goto end;                           // Can't use USE_FRM flag
2283
2279
 
2284
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2285
 
           from, current_pid, thd->thread_id);
 
2280
  snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
 
2281
           from, (unsigned long)current_pid, session->thread_id);
2286
2282
 
2287
2283
  /* If we could open the table, close it */
2288
2284
  if (table_list->table)
2289
2285
  {
2290
2286
    pthread_mutex_lock(&LOCK_open);
2291
 
    close_cached_table(thd, table);
 
2287
    close_cached_table(session, table);
2292
2288
    pthread_mutex_unlock(&LOCK_open);
2293
2289
  }
2294
 
  if (lock_and_wait_for_table_name(thd,table_list))
 
2290
  if (lock_and_wait_for_table_name(session,table_list))
2295
2291
  {
2296
2292
    error= -1;
2297
2293
    goto end;
2299
2295
  if (my_rename(from, tmp, MYF(MY_WME)))
2300
2296
  {
2301
2297
    pthread_mutex_lock(&LOCK_open);
2302
 
    unlock_table_name(thd, table_list);
 
2298
    unlock_table_name(session, table_list);
2303
2299
    pthread_mutex_unlock(&LOCK_open);
2304
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2300
    error= send_check_errmsg(session, table_list, "repair",
2305
2301
                             "Failed renaming data file");
2306
2302
    goto end;
2307
2303
  }
2308
 
  if (mysql_truncate(thd, table_list, 1))
 
2304
  if (mysql_truncate(session, table_list, 1))
2309
2305
  {
2310
2306
    pthread_mutex_lock(&LOCK_open);
2311
 
    unlock_table_name(thd, table_list);
 
2307
    unlock_table_name(session, table_list);
2312
2308
    pthread_mutex_unlock(&LOCK_open);
2313
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2309
    error= send_check_errmsg(session, table_list, "repair",
2314
2310
                             "Failed generating table from .frm file");
2315
2311
    goto end;
2316
2312
  }
2317
2313
  if (my_rename(tmp, from, MYF(MY_WME)))
2318
2314
  {
2319
2315
    pthread_mutex_lock(&LOCK_open);
2320
 
    unlock_table_name(thd, table_list);
 
2316
    unlock_table_name(session, table_list);
2321
2317
    pthread_mutex_unlock(&LOCK_open);
2322
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2318
    error= send_check_errmsg(session, table_list, "repair",
2323
2319
                             "Failed restoring .MYD file");
2324
2320
    goto end;
2325
2321
  }
2329
2325
    to finish the repair in the handler later on.
2330
2326
  */
2331
2327
  pthread_mutex_lock(&LOCK_open);
2332
 
  if (reopen_name_locked_table(thd, table_list, true))
 
2328
  if (reopen_name_locked_table(session, table_list, true))
2333
2329
  {
2334
 
    unlock_table_name(thd, table_list);
 
2330
    unlock_table_name(session, table_list);
2335
2331
    pthread_mutex_unlock(&LOCK_open);
2336
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2332
    error= send_check_errmsg(session, table_list, "repair",
2337
2333
                             "Failed to open partially repaired table");
2338
2334
    goto end;
2339
2335
  }
2343
2339
  if (table == &tmp_table)
2344
2340
  {
2345
2341
    pthread_mutex_lock(&LOCK_open);
2346
 
    closefrm(table, 1);                         // Free allocated memory
 
2342
    table->closefrm(true);                              // Free allocated memory
2347
2343
    pthread_mutex_unlock(&LOCK_open);
2348
2344
  }
2349
2345
  return(error);
2354
2350
/*
2355
2351
  RETURN VALUES
2356
2352
    false Message sent to net (admin operation went ok)
2357
 
    true  Message should be sent by caller 
 
2353
    true  Message should be sent by caller
2358
2354
          (admin operation or network communication failed)
2359
2355
*/
2360
 
static bool mysql_admin_table(THD* thd, TableList* tables,
 
2356
static bool mysql_admin_table(Session* session, TableList* tables,
2361
2357
                              HA_CHECK_OPT* check_opt,
2362
2358
                              const char *operator_name,
2363
2359
                              thr_lock_type lock_type,
2364
2360
                              bool open_for_modify,
2365
2361
                              bool no_warnings_for_error,
2366
2362
                              uint32_t extra_open_options,
2367
 
                              int (*prepare_func)(THD *, TableList *,
 
2363
                              int (*prepare_func)(Session *, TableList *,
2368
2364
                                                  HA_CHECK_OPT *),
2369
 
                              int (handler::*operator_func)(THD *,
 
2365
                              int (handler::*operator_func)(Session *,
2370
2366
                                                            HA_CHECK_OPT *))
2371
2367
{
2372
2368
  TableList *table;
2373
 
  SELECT_LEX *select= &thd->lex->select_lex;
 
2369
  Select_Lex *select= &session->lex->select_lex;
2374
2370
  List<Item> field_list;
2375
2371
  Item *item;
2376
 
  Protocol *protocol= thd->protocol;
2377
 
  LEX *lex= thd->lex;
 
2372
  Protocol *protocol= session->protocol;
 
2373
  LEX *lex= session->lex;
2378
2374
  int result_code= 0;
2379
2375
  const CHARSET_INFO * const cs= system_charset_info;
2380
2376
 
2381
 
  if (end_active_trans(thd))
 
2377
  if (! session->endActiveTransaction())
2382
2378
    return(1);
2383
2379
  field_list.push_back(item = new Item_empty_string("Table",
2384
2380
                                                    NAME_CHAR_LEN * 2,
2394
2390
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2395
2391
    return(true);
2396
2392
 
2397
 
  mysql_ha_rm_tables(thd, tables, false);
2398
 
 
2399
2393
  for (table= tables; table; table= table->next_local)
2400
2394
  {
2401
2395
    char table_name[NAME_LEN*2+2];
2402
2396
    char* db = table->db;
2403
2397
    bool fatal_error=0;
2404
2398
 
2405
 
    strxmov(table_name, db, ".", table->table_name, NULL);
2406
 
    thd->open_options|= extra_open_options;
 
2399
    sprintf(table_name,"%s.%s",db,table->table_name);
 
2400
    session->open_options|= extra_open_options;
2407
2401
    table->lock_type= lock_type;
2408
2402
    /* open only one table from local list of command */
2409
2403
    {
2422
2416
      lex->query_tables= table;
2423
2417
      lex->query_tables_last= &table->next_global;
2424
2418
      lex->query_tables_own_last= 0;
2425
 
      thd->no_warnings_for_error= no_warnings_for_error;
 
2419
      session->no_warnings_for_error= no_warnings_for_error;
2426
2420
 
2427
 
      open_and_lock_tables(thd, table);
2428
 
      thd->no_warnings_for_error= 0;
 
2421
      open_and_lock_tables(session, table);
 
2422
      session->no_warnings_for_error= 0;
2429
2423
      table->next_global= save_next_global;
2430
2424
      table->next_local= save_next_local;
2431
 
      thd->open_options&= ~extra_open_options;
 
2425
      session->open_options&= ~extra_open_options;
2432
2426
    }
2433
2427
 
2434
2428
    if (prepare_func)
2435
2429
    {
2436
 
      switch ((*prepare_func)(thd, table, check_opt)) {
 
2430
      switch ((*prepare_func)(session, table, check_opt)) {
2437
2431
      case  1:           // error, message written to net
2438
 
        ha_autocommit_or_rollback(thd, 1);
2439
 
        end_trans(thd, ROLLBACK);
2440
 
        close_thread_tables(thd);
 
2432
        ha_autocommit_or_rollback(session, 1);
 
2433
        session->endTransaction(ROLLBACK);
 
2434
        close_thread_tables(session);
2441
2435
        continue;
2442
2436
      case -1:           // error, message could be written to net
2443
2437
        /* purecov: begin inspected */
2458
2452
    */
2459
2453
    if (!table->table)
2460
2454
    {
2461
 
      if (!thd->warn_list.elements)
2462
 
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2455
      if (!session->warn_list.elements)
 
2456
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
2463
2457
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2464
2458
      goto send_result;
2465
2459
    }
2476
2470
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2477
2471
                       table_name);
2478
2472
      protocol->store(buff, length, system_charset_info);
2479
 
      ha_autocommit_or_rollback(thd, 0);
2480
 
      end_trans(thd, COMMIT);
2481
 
      close_thread_tables(thd);
 
2473
      ha_autocommit_or_rollback(session, 0);
 
2474
      session->endTransaction(COMMIT);
 
2475
      close_thread_tables(session);
2482
2476
      lex->reset_query_tables_list(false);
2483
2477
      table->table=0;                           // For query cache
2484
2478
      if (protocol->write())
2491
2485
    if (lock_type == TL_WRITE && table->table->s->version)
2492
2486
    {
2493
2487
      pthread_mutex_lock(&LOCK_open);
2494
 
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
 
2488
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2495
2489
                                              "Waiting to get writelock");
2496
 
      mysql_lock_abort(thd,table->table, true);
2497
 
      remove_table_from_cache(thd, table->table->s->db.str,
 
2490
      mysql_lock_abort(session,table->table, true);
 
2491
      remove_table_from_cache(session, table->table->s->db.str,
2498
2492
                              table->table->s->table_name.str,
2499
2493
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2500
2494
                              RTFC_CHECK_KILLED_FLAG);
2501
 
      thd->exit_cond(old_message);
2502
 
      if (thd->killed)
 
2495
      session->exit_cond(old_message);
 
2496
      if (session->killed)
2503
2497
        goto err;
2504
2498
      open_for_modify= 0;
2505
2499
    }
2518
2512
      /* purecov: end */
2519
2513
    }
2520
2514
 
2521
 
    if (operator_func == &handler::ha_repair &&
2522
 
        !(check_opt->sql_flags & TT_USEFRM))
 
2515
    if (operator_func == &handler::ha_repair && !(check_opt->use_frm))
2523
2516
    {
2524
2517
      if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
2525
2518
          (table->table->file->ha_check_for_upgrade(check_opt) ==
2526
2519
           HA_ADMIN_NEEDS_ALTER))
2527
2520
      {
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);
 
2521
        ha_autocommit_or_rollback(session, 1);
 
2522
        close_thread_tables(session);
 
2523
        result_code= mysql_recreate_table(session, table);
2533
2524
        /*
2534
2525
          mysql_recreate_table() can push OK or ERROR.
2535
2526
          Clear 'OK' status. If there is an error, keep it:
2536
 
          we will store the error message in a result set row 
 
2527
          we will store the error message in a result set row
2537
2528
          and then clear.
2538
2529
        */
2539
 
        if (thd->main_da.is_ok())
2540
 
          thd->main_da.reset_diagnostics_area();
 
2530
        if (session->main_da.is_ok())
 
2531
          session->main_da.reset_diagnostics_area();
2541
2532
        goto send_result;
2542
2533
      }
2543
2534
    }
2544
2535
 
2545
 
    result_code = (table->table->file->*operator_func)(thd, check_opt);
 
2536
    result_code = (table->table->file->*operator_func)(session, check_opt);
2546
2537
 
2547
2538
send_result:
2548
2539
 
2549
2540
    lex->cleanup_after_one_table_open();
2550
 
    thd->clear_error();  // these errors shouldn't get client
 
2541
    session->clear_error();  // these errors shouldn't get client
2551
2542
    {
2552
 
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
2543
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2553
2544
      DRIZZLE_ERROR *err;
2554
2545
      while ((err= it++))
2555
2546
      {
2563
2554
        if (protocol->write())
2564
2555
          goto err;
2565
2556
      }
2566
 
      drizzle_reset_errors(thd, true);
 
2557
      drizzle_reset_errors(session, true);
2567
2558
    }
2568
2559
    protocol->prepare_for_resend();
2569
2560
    protocol->store(table_name, system_charset_info);
2582
2573
      }
2583
2574
      break;
2584
2575
 
2585
 
    case HA_ADMIN_NOT_BASE_TABLE:
2586
 
      {
2587
 
        char buf[ERRMSGSIZE+20];
2588
 
        uint32_t 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);
2592
 
      }
2593
 
      break;
2594
 
 
2595
2576
    case HA_ADMIN_OK:
2596
2577
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
2597
2578
      protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
2635
2616
        "try with alter", so here we close the table, do an ALTER Table,
2636
2617
        reopen the table and do ha_innobase::analyze() on it.
2637
2618
      */
2638
 
      ha_autocommit_or_rollback(thd, 0);
2639
 
      close_thread_tables(thd);
 
2619
      ha_autocommit_or_rollback(session, 0);
 
2620
      close_thread_tables(session);
2640
2621
      TableList *save_next_local= table->next_local,
2641
2622
                 *save_next_global= table->next_global;
2642
2623
      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);
 
2624
      result_code= mysql_recreate_table(session, table);
2646
2625
      /*
2647
2626
        mysql_recreate_table() can push OK or ERROR.
2648
2627
        Clear 'OK' status. If there is an error, keep it:
2649
 
        we will store the error message in a result set row 
 
2628
        we will store the error message in a result set row
2650
2629
        and then clear.
2651
2630
      */
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);
 
2631
      if (session->main_da.is_ok())
 
2632
        session->main_da.reset_diagnostics_area();
 
2633
      ha_autocommit_or_rollback(session, 0);
 
2634
      close_thread_tables(session);
2656
2635
      if (!result_code) // recreation went ok
2657
2636
      {
2658
 
        if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
2659
 
            ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
 
2637
        if ((table->table= open_ltable(session, table, lock_type, 0)) &&
 
2638
            ((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2660
2639
          result_code= 0; // analyze went ok
2661
2640
      }
2662
2641
      if (result_code) // either mysql_recreate_table or analyze failed
2663
2642
      {
2664
 
        assert(thd->is_error());
2665
 
        if (thd->is_error())
 
2643
        assert(session->is_error());
 
2644
        if (session->is_error())
2666
2645
        {
2667
 
          const char *err_msg= thd->main_da.message();
2668
 
          if (!thd->vio_ok())
 
2646
          const char *err_msg= session->main_da.message();
 
2647
          if (!session->drizzleclient_vio_ok())
2669
2648
          {
2670
 
            sql_print_error(err_msg);
 
2649
            errmsg_printf(ERRMSG_LVL_ERROR, "%s", err_msg);
2671
2650
          }
2672
2651
          else
2673
2652
          {
2680
2659
            protocol->store(table_name, system_charset_info);
2681
2660
            protocol->store(operator_name, system_charset_info);
2682
2661
          }
2683
 
          thd->clear_error();
 
2662
          session->clear_error();
2684
2663
        }
2685
2664
      }
2686
2665
      result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
2688
2667
      table->next_global= save_next_global;
2689
2668
      goto send_result_message;
2690
2669
    }
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
2670
    case HA_ADMIN_NEEDS_UPGRADE:
2700
2671
    case HA_ADMIN_NEEDS_ALTER:
2701
2672
    {
2732
2703
        else
2733
2704
        {
2734
2705
          pthread_mutex_lock(&LOCK_open);
2735
 
          remove_table_from_cache(thd, table->table->s->db.str,
 
2706
          remove_table_from_cache(session, table->table->s->db.str,
2736
2707
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
2737
2708
          pthread_mutex_unlock(&LOCK_open);
2738
2709
        }
2739
2710
      }
2740
2711
    }
2741
 
    ha_autocommit_or_rollback(thd, 0);
2742
 
    end_trans(thd, COMMIT);
2743
 
    close_thread_tables(thd);
 
2712
    ha_autocommit_or_rollback(session, 0);
 
2713
    session->endTransaction(COMMIT);
 
2714
    close_thread_tables(session);
2744
2715
    table->table=0;                             // For query cache
2745
2716
    if (protocol->write())
2746
2717
      goto err;
2747
2718
  }
2748
2719
 
2749
 
  my_eof(thd);
 
2720
  session->my_eof();
2750
2721
  return(false);
2751
2722
 
2752
2723
err:
2753
 
  ha_autocommit_or_rollback(thd, 1);
2754
 
  end_trans(thd, ROLLBACK);
2755
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
2724
  ha_autocommit_or_rollback(session, 1);
 
2725
  session->endTransaction(ROLLBACK);
 
2726
  close_thread_tables(session);                 // Shouldn't be needed
2756
2727
  if (table)
2757
2728
    table->table=0;
2758
2729
  return(true);
2759
2730
}
2760
2731
 
2761
2732
 
2762
 
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2733
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2763
2734
{
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));
 
2735
  return(mysql_admin_table(session, tables, check_opt,
 
2736
                           "repair", TL_WRITE, 1,
 
2737
                           check_opt->use_frm,
 
2738
                           HA_OPEN_FOR_REPAIR,
 
2739
                           &prepare_for_repair,
 
2740
                           &handler::ha_repair));
2770
2741
}
2771
2742
 
2772
2743
 
2773
 
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2744
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2774
2745
{
2775
 
  return(mysql_admin_table(thd, tables, check_opt,
2776
 
                                "optimize", TL_WRITE, 1,0,0,0,
2777
 
                                &handler::ha_optimize));
 
2746
  return(mysql_admin_table(session, tables, check_opt,
 
2747
                           "optimize", TL_WRITE, 1,0,0,0,
 
2748
                           &handler::ha_optimize));
2778
2749
}
2779
2750
 
2780
2751
 
2783
2754
 
2784
2755
  SYNOPSIS
2785
2756
    mysql_assign_to_keycache()
2786
 
    thd         Thread object
 
2757
    session             Thread object
2787
2758
    tables      Table list (one table only)
2788
2759
 
2789
2760
  RETURN VALUES
2791
2762
   true  error
2792
2763
*/
2793
2764
 
2794
 
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
 
2765
bool mysql_assign_to_keycache(Session* session, TableList* tables,
2795
2766
                             LEX_STRING *key_cache_name)
2796
2767
{
2797
2768
  HA_CHECK_OPT check_opt;
2807
2778
  }
2808
2779
  pthread_mutex_unlock(&LOCK_global_system_variables);
2809
2780
  check_opt.key_cache= key_cache;
2810
 
  return(mysql_admin_table(thd, tables, &check_opt,
 
2781
  return(mysql_admin_table(session, tables, &check_opt,
2811
2782
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
2812
2783
                                0, 0, &handler::assign_to_keycache));
2813
2784
}
2818
2789
 
2819
2790
  SYNOPSIS
2820
2791
    reassign_keycache_tables()
2821
 
    thd         Thread object
 
2792
    session             Thread object
2822
2793
    src_cache   Reference to the key cache to clean up
2823
2794
    dest_cache  New key cache
2824
2795
 
2838
2809
    0     ok
2839
2810
*/
2840
2811
 
2841
 
int reassign_keycache_tables(THD *thd __attribute__((unused)),
 
2812
int reassign_keycache_tables(Session *,
2842
2813
                             KEY_CACHE *src_cache,
2843
2814
                             KEY_CACHE *dst_cache)
2844
2815
{
2853
2824
/**
2854
2825
  @brief          Create frm file based on I_S table
2855
2826
 
2856
 
  @param[in]      thd                      thread handler
2857
 
  @param[in]      schema_table             I_S table           
 
2827
  @param[in]      session                      thread handler
 
2828
  @param[in]      schema_table             I_S table
2858
2829
  @param[in]      dst_path                 path where frm should be created
2859
2830
  @param[in]      create_info              Create info
2860
2831
 
2862
2833
    @retval       0                        success
2863
2834
    @retval       1                        error
2864
2835
*/
2865
 
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
 
2836
bool mysql_create_like_schema_frm(Session* session, TableList* schema_table,
2866
2837
                                  char *dst_path, HA_CREATE_INFO *create_info)
2867
2838
{
2868
2839
  HA_CREATE_INFO local_create_info;
2877
2848
  local_create_info.default_table_charset=default_charset_info;
2878
2849
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2879
2850
  schema_table->table->use_all_columns();
2880
 
  if (mysql_prepare_alter_table(thd, schema_table->table,
 
2851
  if (mysql_prepare_alter_table(session, schema_table->table,
2881
2852
                                &local_create_info, &alter_info))
2882
 
    return(1);
2883
 
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
 
2853
    return true;
 
2854
 
 
2855
  if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2884
2856
                                 tmp_table, &db_options,
2885
2857
                                 schema_table->table->file,
2886
2858
                                 &schema_table->table->s->key_info, &keys, 0))
2887
 
    return(1);
 
2859
    return true;
 
2860
 
2888
2861
  local_create_info.max_rows= 0;
2889
 
  if (mysql_create_frm(thd, dst_path, NULL, NULL,
 
2862
  if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
2890
2863
                       &local_create_info, alter_info.create_list,
2891
2864
                       keys, schema_table->table->s->key_info,
2892
 
                       schema_table->table->file))
2893
 
    return(1);
2894
 
  return(0);
 
2865
                       schema_table->table->file, true))
 
2866
    return true;
 
2867
 
 
2868
  return false;
2895
2869
}
2896
2870
 
2897
 
 
2898
2871
/*
2899
2872
  Create a table identical to the specified table
2900
2873
 
2901
2874
  SYNOPSIS
2902
2875
    mysql_create_like_table()
2903
 
    thd         Thread object
 
2876
    session             Thread object
2904
2877
    table       Table list element for target table
2905
2878
    src_table   Table list element for source table
2906
2879
    create_info Create info
2910
2883
    true  error
2911
2884
*/
2912
2885
 
2913
 
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
 
2886
bool mysql_create_like_table(Session* session, TableList* table, TableList* src_table,
2914
2887
                             HA_CREATE_INFO *create_info)
2915
2888
{
2916
2889
  Table *name_lock= 0;
2931
2904
    we ensure that our statement is properly isolated from all concurrent
2932
2905
    operations which matter.
2933
2906
  */
2934
 
  if (open_tables(thd, &src_table, &not_used, 0))
 
2907
  if (open_tables(session, &src_table, &not_used, 0))
2935
2908
    return(true);
2936
2909
 
2937
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
 
2910
  strncpy(src_path, src_table->table->s->path.str, sizeof(src_path));
2938
2911
 
2939
 
  /* 
 
2912
  /*
2940
2913
    Check that destination tables does not exist. Note that its name
2941
2914
    was already checked when it was added to the table list.
2942
2915
  */
2943
2916
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2944
2917
  {
2945
 
    if (find_temporary_table(thd, db, table_name))
 
2918
    if (find_temporary_table(session, db, table_name))
2946
2919
      goto table_exists;
2947
 
    dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
 
2920
    dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2948
2921
    create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2949
2922
  }
2950
2923
  else
2951
2924
  {
2952
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
2925
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2953
2926
      goto err;
2954
2927
    if (!name_lock)
2955
2928
      goto table_exists;
2956
2929
    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))
 
2930
                                          db, table_name, "", 0);
 
2931
    if (table_proto_exists(dst_path)==EEXIST)
2959
2932
      goto table_exists;
2960
2933
  }
2961
2934
 
2975
2948
  pthread_mutex_lock(&LOCK_open);
2976
2949
  if (src_table->schema_table)
2977
2950
  {
2978
 
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
 
2951
    if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
2979
2952
    {
2980
2953
      pthread_mutex_unlock(&LOCK_open);
2981
2954
      goto err;
2982
2955
    }
2983
2956
  }
2984
 
  else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
 
2957
  else
2985
2958
  {
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
 
    pthread_mutex_unlock(&LOCK_open);
2991
 
    goto err;
 
2959
    int dfecopyr= copy_table_proto_file(src_path, dst_path);
 
2960
 
 
2961
    if(dfecopyr)
 
2962
    {
 
2963
      if (my_errno == ENOENT)
 
2964
        my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
2965
      else
 
2966
        my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
 
2967
      pthread_mutex_unlock(&LOCK_open);
 
2968
      goto err;
 
2969
    }
2992
2970
  }
2993
2971
 
2994
2972
  /*
2996
2974
    creation, instead create the table directly (for both normal
2997
2975
    and temporary tables).
2998
2976
  */
2999
 
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
3000
 
  if (thd->variables.keep_files_on_create)
 
2977
 
 
2978
  if (session->variables.keep_files_on_create)
3001
2979
    create_info->options|= HA_CREATE_KEEP_FILES;
3002
 
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
 
2980
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
3003
2981
  pthread_mutex_unlock(&LOCK_open);
3004
2982
 
3005
2983
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3006
2984
  {
3007
 
    if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
 
2985
    if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3008
2986
                                     OTM_OPEN))
3009
2987
    {
3010
2988
      (void) rm_temporary_table(create_info->db_type,
3011
 
                                dst_path, false); /* purecov: inspected */
 
2989
                                dst_path);
3012
2990
      goto err;     /* purecov: inspected */
3013
2991
    }
3014
2992
  }
3022
3000
  /*
3023
3001
    We have to write the query before we unlock the tables.
3024
3002
  */
3025
 
  if (thd->current_stmt_binlog_row_based)
3026
3003
  {
3027
3004
    /*
3028
3005
       Since temporary tables are not replicated under row-based
3056
3033
        */
3057
3034
        table->table= name_lock;
3058
3035
        pthread_mutex_lock(&LOCK_open);
3059
 
        if (reopen_name_locked_table(thd, table, false))
 
3036
        if (reopen_name_locked_table(session, table, false))
3060
3037
        {
3061
3038
          pthread_mutex_unlock(&LOCK_open);
3062
3039
          goto err;
3063
3040
        }
3064
3041
        pthread_mutex_unlock(&LOCK_open);
3065
3042
 
3066
 
        int result= store_create_info(thd, table, &query,
 
3043
        int result= store_create_info(session, table, &query,
3067
3044
                                               create_info);
3068
3045
 
3069
3046
        assert(result == 0); // store_create_info() always return 0
3070
 
        write_bin_log(thd, true, query.ptr(), query.length());
 
3047
        write_bin_log(session, true, query.ptr(), query.length());
3071
3048
      }
3072
3049
      else                                      // Case 1
3073
 
        write_bin_log(thd, true, thd->query, thd->query_length);
 
3050
        write_bin_log(session, true, session->query, session->query_length);
3074
3051
    }
3075
3052
    /*
3076
3053
      Case 3 and 4 does nothing under RBR
3077
3054
    */
3078
3055
  }
3079
 
  else
3080
 
    write_bin_log(thd, true, thd->query, thd->query_length);
3081
3056
 
3082
3057
  res= false;
3083
3058
  goto err;
3088
3063
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
3089
3064
    snprintf(warn_buff, sizeof(warn_buff),
3090
3065
             ER(ER_TABLE_EXISTS_ERROR), table_name);
3091
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3066
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3092
3067
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3093
3068
    res= false;
3094
3069
  }
3099
3074
  if (name_lock)
3100
3075
  {
3101
3076
    pthread_mutex_lock(&LOCK_open);
3102
 
    unlink_open_table(thd, name_lock, false);
 
3077
    unlink_open_table(session, name_lock, false);
3103
3078
    pthread_mutex_unlock(&LOCK_open);
3104
3079
  }
3105
3080
  return(res);
3106
3081
}
3107
3082
 
3108
3083
 
3109
 
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3084
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3110
3085
{
3111
3086
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3112
3087
 
3113
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3088
  return(mysql_admin_table(session, tables, check_opt,
3114
3089
                                "analyze", lock_type, 1, 0, 0, 0,
3115
3090
                                &handler::ha_analyze));
3116
3091
}
3117
3092
 
3118
3093
 
3119
 
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
 
3094
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3120
3095
{
3121
3096
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3122
3097
 
3123
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3098
  return(mysql_admin_table(session, tables, check_opt,
3124
3099
                                "check", lock_type,
3125
3100
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
3126
3101
                                &handler::ha_check));
3129
3104
 
3130
3105
/* table_list should contain just one table */
3131
3106
static int
3132
 
mysql_discard_or_import_tablespace(THD *thd,
 
3107
mysql_discard_or_import_tablespace(Session *session,
3133
3108
                                   TableList *table_list,
3134
3109
                                   enum tablespace_op_type tablespace_op)
3135
3110
{
3142
3117
    ALTER Table
3143
3118
  */
3144
3119
 
3145
 
  thd_proc_info(thd, "discard_or_import_tablespace");
 
3120
  session->set_proc_info("discard_or_import_tablespace");
3146
3121
 
3147
3122
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3148
3123
 
3150
3125
   We set this flag so that ha_innobase::open and ::external_lock() do
3151
3126
   not complain when we lock the table
3152
3127
 */
3153
 
  thd->tablespace_op= true;
3154
 
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
 
3128
  session->tablespace_op= true;
 
3129
  if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3155
3130
  {
3156
 
    thd->tablespace_op=false;
 
3131
    session->tablespace_op=false;
3157
3132
    return(-1);
3158
3133
  }
3159
3134
 
3160
3135
  error= table->file->ha_discard_or_import_tablespace(discard);
3161
3136
 
3162
 
  thd_proc_info(thd, "end");
 
3137
  session->set_proc_info("end");
3163
3138
 
3164
3139
  if (error)
3165
3140
    goto err;
3166
3141
 
3167
3142
  /* The ALTER Table is always in its own transaction */
3168
 
  error = ha_autocommit_or_rollback(thd, 0);
3169
 
  if (end_active_trans(thd))
 
3143
  error = ha_autocommit_or_rollback(session, 0);
 
3144
  if (! session->endActiveTransaction())
3170
3145
    error=1;
3171
3146
  if (error)
3172
3147
    goto err;
3173
 
  write_bin_log(thd, false, thd->query, thd->query_length);
 
3148
  write_bin_log(session, false, session->query, session->query_length);
3174
3149
 
3175
3150
err:
3176
 
  ha_autocommit_or_rollback(thd, error);
3177
 
  thd->tablespace_op=false;
3178
 
  
 
3151
  ha_autocommit_or_rollback(session, error);
 
3152
  session->tablespace_op=false;
 
3153
 
3179
3154
  if (error == 0)
3180
3155
  {
3181
 
    my_ok(thd);
 
3156
    session->my_ok();
3182
3157
    return(0);
3183
3158
  }
3184
3159
 
3185
3160
  table->file->print_error(error, MYF(0));
3186
 
    
 
3161
 
3187
3162
  return(-1);
3188
3163
}
3189
3164
 
3223
3198
 
3224
3199
 
3225
3200
/**
3226
 
   @param       thd                Thread
 
3201
   @param       session                Thread
3227
3202
   @param       table              The original table.
3228
3203
   @param       alter_info         Alter options, fields and keys for the new
3229
3204
                                   table.
3255
3230
 
3256
3231
static
3257
3232
bool
3258
 
compare_tables(THD *thd,
 
3233
compare_tables(Session *session,
3259
3234
               Table *table,
3260
3235
               Alter_info *alter_info,
3261
 
                           HA_CREATE_INFO *create_info,
 
3236
               HA_CREATE_INFO *create_info,
3262
3237
               uint32_t order_num,
3263
3238
               HA_ALTER_FLAGS *alter_flags,
3264
3239
               HA_ALTER_INFO *ha_alter_info,
3270
3245
  Create_field *new_field;
3271
3246
  KEY_PART_INFO *key_part;
3272
3247
  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
3248
 
3279
3249
  {
3280
3250
    /*
3292
3262
      to evaluate possibility of fast ALTER Table, and then
3293
3263
      destroy the copy.
3294
3264
    */
3295
 
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
3296
 
    THD *thd= table->in_use;
 
3265
    Alter_info tmp_alter_info(*alter_info, session->mem_root);
 
3266
    session= table->in_use;
3297
3267
    uint32_t db_options= 0; /* not used */
3298
3268
    /* Create the prepared information. */
3299
 
    if (mysql_prepare_create_table(thd, create_info,
 
3269
    if (mysql_prepare_create_table(session, create_info,
3300
3270
                                   &tmp_alter_info,
3301
3271
                                   (table->s->tmp_table != NO_TMP_TABLE),
3302
3272
                                   &db_options,
3307
3277
      return(true);
3308
3278
    /* Allocate result buffers. */
3309
3279
    if (! (ha_alter_info->index_drop_buffer=
3310
 
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
 
3280
           (uint*) session->alloc(sizeof(uint32_t) * table->s->keys)) ||
3311
3281
        ! (ha_alter_info->index_add_buffer=
3312
 
           (uint*) thd->alloc(sizeof(uint) *
 
3282
           (uint*) session->alloc(sizeof(uint32_t) *
3313
3283
                              tmp_alter_info.key_list.elements)))
3314
3284
      return(true);
3315
3285
  }
3355
3325
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3356
3326
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3357
3327
      order_num ||
3358
 
      !table->s->mysql_version ||
3359
 
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
 
3328
      !table->s->mysql_version)
3360
3329
  {
3361
3330
    *table_changes= IS_EQUAL_NO;
3362
3331
    /*
3378
3347
    /* TODO check for ADD/DROP FOREIGN KEY */
3379
3348
    if (alter_info->flags & ALTER_FOREIGN_KEY)
3380
3349
      *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
3350
  }
3385
3351
  /*
3386
3352
    Go through fields and check if the original ones are compatible
3407
3373
      if (!(table_changes_local= field->is_equal(new_field)))
3408
3374
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3409
3375
 
 
3376
      /*
 
3377
        Check if the altered column is a stored virtual field.
 
3378
        TODO: Mark such a column with an alter flag only if
 
3379
        the expression functions are not equal.
 
3380
      */
 
3381
      if (field->is_stored && field->vcol_info)
 
3382
        *alter_flags|= HA_ALTER_STORED_VCOL;
 
3383
 
3410
3384
      /* Check if field was renamed */
3411
3385
      field->flags&= ~FIELD_IS_RENAMED;
3412
3386
      if (my_strcasecmp(system_charset_info,
3423
3397
 
3424
3398
      /* Check that NULL behavior is same for old and new fields */
3425
3399
      if ((new_field->flags & NOT_NULL_FLAG) !=
3426
 
          (uint) (field->flags & NOT_NULL_FLAG))
 
3400
          (uint32_t) (field->flags & NOT_NULL_FLAG))
3427
3401
      {
3428
3402
        *table_changes= IS_EQUAL_NO;
3429
3403
        *alter_flags|= HA_ALTER_COLUMN_NULLABLE;
3472
3446
      if (table_key->flags & HA_NOSAME)
3473
3447
      {
3474
3448
        /* Unique key. Check for "PRIMARY". */
3475
 
        if (! my_strcasecmp(system_charset_info,
3476
 
                            table_key->name, primary_key_name))
 
3449
        if (is_primary_key(table_key))
3477
3450
          *alter_flags|= HA_DROP_PK_INDEX;
3478
3451
        else
3479
3452
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
3493
3466
      if (table_key->flags & HA_NOSAME)
3494
3467
      {
3495
3468
        // Unique key. Check for "PRIMARY".
3496
 
        if (! my_strcasecmp(system_charset_info,
3497
 
                            table_key->name, primary_key_name))
 
3469
        if (is_primary_key(table_key))
3498
3470
          *alter_flags|= HA_ALTER_PK_INDEX;
3499
3471
        else
3500
3472
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3523
3495
        if (table_key->flags & HA_NOSAME)
3524
3496
        {
3525
3497
          /* Unique key. Check for "PRIMARY" */
3526
 
          if (! my_strcasecmp(system_charset_info,
3527
 
                              table_key->name, primary_key_name))
 
3498
          if (is_primary_key(table_key))
3528
3499
            *alter_flags|= HA_ALTER_PK_INDEX;
3529
3500
          else
3530
3501
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3586
3557
      if (new_key->flags & HA_NOSAME)
3587
3558
      {
3588
3559
        /* Unique key. Check for "PRIMARY" */
3589
 
        if (! my_strcasecmp(system_charset_info,
3590
 
                            new_key->name, primary_key_name))
 
3560
        if (is_primary_key(new_key))
3591
3561
          *alter_flags|= HA_ADD_PK_INDEX;
3592
3562
        else
3593
3563
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
3636
3606
 
3637
3607
  if (error == HA_ERR_WRONG_COMMAND)
3638
3608
  {
3639
 
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3609
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3640
3610
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3641
3611
                        table->s->table_name.str);
3642
3612
    error= 0;
3646
3616
  return(error);
3647
3617
}
3648
3618
 
3649
 
int create_temporary_table(THD *thd,
 
3619
int create_temporary_table(Session *session,
3650
3620
                           Table *table,
3651
3621
                           char *new_db,
3652
3622
                           char *tmp_name,
3656
3626
{
3657
3627
  int error;
3658
3628
  char index_file[FN_REFLEN], data_file[FN_REFLEN];
3659
 
  handlerton *old_db_type, *new_db_type;
 
3629
  StorageEngine *old_db_type, *new_db_type;
3660
3630
  old_db_type= table->s->db_type();
3661
3631
  new_db_type= create_info->db_type;
3662
3632
  /*
3688
3658
    if (create_info->index_file_name)
3689
3659
    {
3690
3660
      /* Fix index_file_name to have 'tmp_name' as basename */
3691
 
      my_stpcpy(index_file, tmp_name);
 
3661
      strcpy(index_file, tmp_name);
3692
3662
      create_info->index_file_name=fn_same(index_file,
3693
3663
                                           create_info->index_file_name,
3694
3664
                                           1);
3696
3666
    if (create_info->data_file_name)
3697
3667
    {
3698
3668
      /* Fix data_file_name to have 'tmp_name' as basename */
3699
 
      my_stpcpy(data_file, tmp_name);
 
3669
      strcpy(data_file, tmp_name);
3700
3670
      create_info->data_file_name=fn_same(data_file,
3701
3671
                                          create_info->data_file_name,
3702
3672
                                          1);
3707
3677
 
3708
3678
  /*
3709
3679
    Create a table with a temporary name.
3710
 
    With create_info->frm_only == 1 this creates a .frm file only.
3711
3680
    We don't log the statement, it will be logged later.
3712
3681
  */
3713
 
  tmp_disable_binlog(thd);
3714
 
  error= mysql_create_table(thd, new_db, tmp_name,
 
3682
  error= mysql_create_table(session, new_db, tmp_name,
3715
3683
                            create_info, alter_info, 1, 0);
3716
 
  reenable_binlog(thd);
3717
3684
 
3718
3685
  return(error);
3719
3686
}
3724
3691
 
3725
3692
  SYNOPSIS
3726
3693
    create_altered_table()
3727
 
      thd              Thread handle
 
3694
      session              Thread handle
3728
3695
      table            The original table
3729
3696
      create_info      Information from the parsing phase about new
3730
3697
                       table properties.
3738
3705
    The temporary table is created without storing it in any storage engine
3739
3706
    and is opened only to get the table struct and frm file reference.
3740
3707
*/
3741
 
Table *create_altered_table(THD *thd,
 
3708
Table *create_altered_table(Session *session,
3742
3709
                            Table *table,
3743
3710
                            char *new_db,
3744
3711
                            HA_CREATE_INFO *create_info,
3751
3718
  char tmp_name[80];
3752
3719
  char path[FN_REFLEN];
3753
3720
 
3754
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3755
 
           tmp_file_prefix, current_pid, thd->thread_id);
 
3721
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
 
3722
           TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3756
3723
  /* Safety fix for InnoDB */
3757
3724
  if (lower_case_table_names)
3758
3725
    my_casedn_str(files_charset_info, tmp_name);
3759
3726
  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,
 
3727
 
 
3728
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
3762
3729
                                     &altered_create_info,
3763
3730
                                     alter_info, db_change)))
3764
3731
  {
3767
3734
 
3768
3735
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
3769
3736
                       FN_IS_TMP);
3770
 
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
 
3737
  altered_table= open_temporary_table(session, path, new_db, tmp_name, 1,
3771
3738
                                      OTM_ALTER);
3772
3739
  return(altered_table);
3773
 
 
3774
 
  return(NULL);
3775
3740
}
3776
3741
 
3777
3742
 
3780
3745
 
3781
3746
  SYNOPSIS
3782
3747
    mysql_fast_or_online_alter_table()
3783
 
      thd              Thread handle
 
3748
      session              Thread handle
3784
3749
      table            The original table
3785
3750
      altered_table    A temporary table showing how we will change table
3786
3751
      create_info      Information from the parsing phase about new
3800
3765
    operation directly, on-line without mysql having to copy
3801
3766
    the table.
3802
3767
*/
3803
 
int mysql_fast_or_online_alter_table(THD *thd,
 
3768
int mysql_fast_or_online_alter_table(Session *session,
3804
3769
                                     Table *table,
3805
3770
                                     Table *altered_table,
3806
3771
                                     HA_CREATE_INFO *create_info,
3817
3782
   /*
3818
3783
      Tell the handler to prepare for the online alter
3819
3784
    */
3820
 
    if ((error= table->file->alter_table_phase1(thd,
 
3785
    if ((error= table->file->alter_table_phase1(session,
3821
3786
                                                altered_table,
3822
3787
                                                create_info,
3823
3788
                                                alter_info,
3828
3793
 
3829
3794
    /*
3830
3795
       Tell the storage engine to perform the online alter table
3831
 
       TODO: 
 
3796
       TODO:
3832
3797
       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
3833
3798
       we need to wrap the next call with a DDL lock.
3834
3799
     */
3835
 
    if ((error= table->file->alter_table_phase2(thd,
 
3800
    if ((error= table->file->alter_table_phase2(session,
3836
3801
                                                altered_table,
3837
3802
                                                create_info,
3838
3803
                                                alter_info,
3846
3811
    and will be renamed to the original table name.
3847
3812
  */
3848
3813
  pthread_mutex_lock(&LOCK_open);
3849
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
3814
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3850
3815
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3851
3816
                          keys_onoff);
3852
 
  close_data_files_and_morph_locks(thd,
 
3817
  close_data_files_and_morph_locks(session,
3853
3818
                                   table->pos_in_table_list->db,
3854
3819
                                   table->pos_in_table_list->table_name);
3855
3820
  if (mysql_rename_table(NULL,
3871
3836
    wait_if_global_read_lock(), which could create a deadlock if called
3872
3837
    with LOCK_open.
3873
3838
  */
3874
 
  error= ha_autocommit_or_rollback(thd, 0);
 
3839
  error= ha_autocommit_or_rollback(session, 0);
3875
3840
 
3876
 
  if (ha_commit(thd))
 
3841
  if (ha_commit(session))
3877
3842
    error=1;
3878
3843
  if (error)
3879
3844
    goto err;
3892
3857
      Tell the handler that the changed frm is on disk and table
3893
3858
      has been re-opened
3894
3859
   */
3895
 
    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
 
3860
    if ((error= t_table->file->alter_table_phase3(session, t_table)))
3896
3861
    {
3897
3862
      goto err;
3898
3863
    }
3931
3896
  instructions that require change in table data, not only in
3932
3897
  table definition or indexes.
3933
3898
 
3934
 
  @param[in,out]  thd         thread handle. Used as a memory pool
 
3899
  @param[in,out]  session         thread handle. Used as a memory pool
3935
3900
                              and source of environment information.
3936
3901
  @param[in]      table       the source table, open and locked
3937
3902
                              Used as an interface to the storage engine
3958
3923
*/
3959
3924
 
3960
3925
static bool
3961
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
3926
mysql_prepare_alter_table(Session *session, Table *table,
3962
3927
                          HA_CREATE_INFO *create_info,
3963
3928
                          Alter_info *alter_info)
3964
3929
{
4009
3974
    */
4010
3975
  Field **f_ptr,*field;
4011
3976
  for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
4012
 
    {
 
3977
  {
4013
3978
    /* Check if field should be dropped */
4014
3979
    Alter_drop *drop;
4015
3980
    drop_it.rewind();
4017
3982
    {
4018
3983
      if (drop->type == Alter_drop::COLUMN &&
4019
3984
          !my_strcasecmp(system_charset_info,field->field_name, drop->name))
4020
 
    {
 
3985
      {
4021
3986
        /* Reset auto_increment value if it was dropped */
4022
3987
        if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
4023
3988
            !(used_fields & HA_CREATE_USED_AUTO))
4024
 
      {
 
3989
        {
4025
3990
          create_info->auto_increment_value=0;
4026
3991
          create_info->used_fields|=HA_CREATE_USED_AUTO;
 
3992
        }
 
3993
        break;
4027
3994
      }
4028
 
        break;
4029
3995
    }
4030
 
  }
4031
3996
    if (drop)
4032
 
      {
 
3997
    {
4033
3998
      drop_it.remove();
4034
3999
      continue;
4035
4000
    }
4044
4009
    if (def)
4045
4010
    {                                           // Field is changed
4046
4011
      def->field=field;
 
4012
      if (field->is_stored != def->is_stored)
 
4013
      {
 
4014
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
4015
                 MYF(0),
 
4016
                 "Changing the STORED status");
 
4017
        goto err;
 
4018
      }
4047
4019
      if (!def->after)
4048
 
        {
 
4020
      {
4049
4021
        new_create_list.push_back(def);
4050
4022
        def_it.remove();
4051
 
        }
4052
4023
      }
4053
 
      else
4054
 
      {
 
4024
    }
 
4025
    else
 
4026
    {
4055
4027
      /*
4056
4028
        This field was not dropped and not changed, add it to the list
4057
4029
        for the new table.
4061
4033
      alter_it.rewind();                        // Change default if ALTER
4062
4034
      Alter_column *alter;
4063
4035
      while ((alter=alter_it++))
4064
 
        {
 
4036
      {
4065
4037
        if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
4066
4038
          break;
4067
 
        }
 
4039
      }
4068
4040
      if (alter)
4069
 
        {
 
4041
      {
4070
4042
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
4071
4043
        {
4072
4044
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
4088
4060
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
4089
4061
      goto err;
4090
4062
    }
4091
 
      /*
 
4063
    /*
4092
4064
      Check that the DATE/DATETIME not null field we are going to add is
4093
4065
      either has a default value or the '0000-00-00' is allowed by the
4094
4066
      set sql mode.
4095
4067
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4096
4068
      flag to allow ALTER Table only if the table to be altered is empty.
4097
 
      */
4098
 
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
 
4069
    */
 
4070
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4099
4071
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4100
 
         !alter_info->datetime_field &&
4101
 
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4102
 
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
 
4072
        !alter_info->datetime_field &&
 
4073
        !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
 
4074
        session->variables.sql_mode & MODE_NO_ZERO_DATE)
4103
4075
    {
4104
 
        alter_info->datetime_field= def;
4105
 
        alter_info->error_if_not_empty= true;
 
4076
      alter_info->datetime_field= def;
 
4077
      alter_info->error_if_not_empty= true;
4106
4078
    }
4107
4079
    if (!def->after)
4108
4080
      new_create_list.push_back(def);
4116
4088
      {
4117
4089
        if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
4118
4090
          break;
4119
 
  }
 
4091
      }
4120
4092
      if (!find)
4121
 
  {
 
4093
      {
4122
4094
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
4123
 
    goto err;
4124
 
  }
 
4095
        goto err;
 
4096
      }
4125
4097
      find_it.after(def);                       // Put element after this
4126
4098
      /*
4127
4099
        XXX: hack for Bug#28427.
4135
4107
      */
4136
4108
      if (alter_info->build_method == HA_BUILD_ONLINE)
4137
4109
      {
4138
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4110
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4139
4111
        goto err;
4140
4112
      }
4141
4113
      alter_info->build_method= HA_BUILD_OFFLINE;
4146
4118
    my_error(ER_BAD_FIELD_ERROR, MYF(0),
4147
4119
             alter_info->alter_list.head()->name, table->s->table_name.str);
4148
4120
    goto err;
4149
 
    }
 
4121
  }
4150
4122
  if (!new_create_list.elements)
4151
 
    {
 
4123
  {
4152
4124
    my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS),
4153
4125
               MYF(0));
4154
4126
    goto err;
4155
 
    }
 
4127
  }
4156
4128
 
4157
 
    /*
 
4129
  /*
4158
4130
    Collect all keys which isn't in drop list. Add only those
4159
4131
    for which some fields exists.
4160
 
    */
 
4132
  */
4161
4133
 
4162
4134
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
4163
 
    {
 
4135
  {
4164
4136
    char *key_name= key_info->name;
4165
4137
    Alter_drop *drop;
4166
4138
    drop_it.rewind();
4167
4139
    while ((drop=drop_it++))
4168
 
      {
 
4140
    {
4169
4141
      if (drop->type == Alter_drop::KEY &&
4170
4142
          !my_strcasecmp(system_charset_info,key_name, drop->name))
4171
4143
        break;
4172
 
      }
 
4144
    }
4173
4145
    if (drop)
4174
 
        {
 
4146
    {
4175
4147
      drop_it.remove();
4176
4148
      continue;
4177
4149
    }
4186
4158
      Create_field *cfield;
4187
4159
      field_it.rewind();
4188
4160
      while ((cfield=field_it++))
4189
 
    {
 
4161
      {
4190
4162
        if (cfield->change)
4191
 
    {
 
4163
        {
4192
4164
          if (!my_strcasecmp(system_charset_info, key_part_name,
4193
4165
                             cfield->change))
4194
4166
            break;
4242
4214
 
4243
4215
      if (key_info->flags & HA_NOSAME)
4244
4216
      {
4245
 
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
 
4217
        if (is_primary_key_name(key_name))
4246
4218
          key_type= Key::PRIMARY;
4247
4219
        else
4248
4220
          key_type= Key::UNIQUE;
4261
4233
    Key *key;
4262
4234
    while ((key=key_it++))                      // Add new keys
4263
4235
    {
 
4236
      if (key->type == Key::FOREIGN_KEY &&
 
4237
          ((Foreign_key *)key)->validate(new_create_list))
 
4238
        goto err;
4264
4239
      if (key->type != Key::FOREIGN_KEY)
4265
4240
        new_key_list.push_back(key);
4266
 
      if (key->name.str &&
4267
 
          !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
 
4241
      if (key->name.str && is_primary_key_name(key->name.str))
4268
4242
      {
4269
4243
        my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
4270
4244
        goto err;
4321
4295
 
4322
4296
  SYNOPSIS
4323
4297
    mysql_alter_table()
4324
 
      thd              Thread handle
 
4298
      session              Thread handle
4325
4299
      new_db           If there is a RENAME clause
4326
4300
      new_name         If there is a RENAME clause
4327
4301
      create_info      Information from the parsing phase about new
4358
4332
    true   Error
4359
4333
*/
4360
4334
 
4361
 
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 
4335
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4362
4336
                       HA_CREATE_INFO *create_info,
4363
4337
                       TableList *table_list,
4364
4338
                       Alter_info *alter_info,
4365
4339
                       uint32_t order_num, order_st *order, bool ignore)
4366
4340
{
4367
4341
  Table *table, *new_table=0, *name_lock= 0;;
 
4342
  string new_name_str;
4368
4343
  int error= 0;
4369
4344
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4370
4345
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4371
4346
  char path[FN_REFLEN];
4372
4347
  ha_rows copied= 0,deleted= 0;
4373
 
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4374
 
  legacy_db_type table_type;
 
4348
  StorageEngine *old_db_type, *new_db_type, *save_old_db_type;
 
4349
 
 
4350
  new_name_buff[0]= '\0';
4375
4351
 
4376
4352
  if (table_list && table_list->schema_table)
4377
4353
  {
4378
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
4354
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4379
4355
    return(true);
4380
4356
  }
4381
4357
 
4384
4360
    to simplify further comparisons: we want to see if it's a RENAME
4385
4361
    later just by comparing the pointers, avoiding the need for strcmp.
4386
4362
  */
4387
 
  thd_proc_info(thd, "init");
 
4363
  session->set_proc_info("init");
4388
4364
  table_name=table_list->table_name;
4389
4365
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4390
4366
  db=table_list->db;
4392
4368
    new_db= db;
4393
4369
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
4394
4370
 
4395
 
  mysql_ha_rm_tables(thd, table_list, false);
4396
 
 
4397
4371
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4398
4372
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4399
4373
    /* Conditionally writes to binlog. */
4400
 
    return(mysql_discard_or_import_tablespace(thd,table_list,
 
4374
    return(mysql_discard_or_import_tablespace(session,table_list,
4401
4375
                                              alter_info->tablespace_op));
4402
 
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
4403
 
           "/", table_name, reg_ext, NULL);
4404
 
  (void) unpack_filename(new_name_buff, new_name_buff);
 
4376
  ostringstream oss;
 
4377
  oss << drizzle_data_home << "/" << db << "/" << table_name;
 
4378
 
 
4379
  (void) unpack_filename(new_name_buff, oss.str().c_str());
4405
4380
  /*
4406
4381
    If this is just a rename of a view, short cut to the
4407
4382
    following scenario: 1) lock LOCK_open 2) do a RENAME
4415
4390
    into the main table list, like open_tables does).
4416
4391
    This code is wrong and will be removed, please do not copy.
4417
4392
  */
4418
 
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
4419
4393
 
4420
 
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
 
4394
  if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4421
4395
    return(true);
4422
4396
  table->use_all_columns();
4423
4397
 
4424
4398
  /* Check that we are not trying to rename to an existing table */
4425
4399
  if (new_name)
4426
4400
  {
4427
 
    my_stpcpy(new_name_buff,new_name);
4428
 
    my_stpcpy(new_alias= new_alias_buff, new_name);
 
4401
    strcpy(new_name_buff,new_name);
 
4402
    strcpy(new_alias= new_alias_buff, new_name);
4429
4403
    if (lower_case_table_names)
4430
4404
    {
4431
4405
      if (lower_case_table_names != 2)
4432
4406
      {
4433
 
        my_casedn_str(files_charset_info, new_name_buff);
4434
 
        new_alias= new_name;                    // Create lower case table name
 
4407
        my_casedn_str(files_charset_info, new_name_buff);
 
4408
        new_alias= new_name;                    // Create lower case table name
4435
4409
      }
4436
4410
      my_casedn_str(files_charset_info, new_name);
4437
4411
    }
4448
4422
    {
4449
4423
      if (table->s->tmp_table != NO_TMP_TABLE)
4450
4424
      {
4451
 
        if (find_temporary_table(thd,new_db,new_name_buff))
 
4425
        if (find_temporary_table(session,new_db,new_name_buff))
4452
4426
        {
4453
4427
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
4454
4428
          return(true);
4456
4430
      }
4457
4431
      else
4458
4432
      {
4459
 
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
 
4433
        if (lock_table_name_if_not_cached(session, new_db, new_name, &name_lock))
4460
4434
          return(true);
4461
4435
        if (!name_lock)
4462
4436
        {
4465
4439
        }
4466
4440
 
4467
4441
        build_table_filename(new_name_buff, sizeof(new_name_buff),
4468
 
                             new_db, new_name_buff, reg_ext, 0);
4469
 
        if (!access(new_name_buff, F_OK))
 
4442
                             new_db, new_name_buff, "", 0);
 
4443
        if (table_proto_exists(new_name_buff)==EEXIST)
4470
4444
        {
4471
 
          /* Table will be closed in do_command() */
 
4445
          /* Table will be closed by Session::executeCommand() */
4472
4446
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
4473
4447
          goto err;
4474
4448
        }
4487
4461
    create_info->db_type= old_db_type;
4488
4462
  }
4489
4463
 
4490
 
  if (check_engine(thd, new_name, create_info))
 
4464
  if (check_engine(session, new_name, create_info))
4491
4465
    goto err;
4492
4466
  new_db_type= create_info->db_type;
4493
4467
 
4502
4476
  if (create_info->row_type == ROW_TYPE_NOT_USED)
4503
4477
    create_info->row_type= table->s->row_type;
4504
4478
 
4505
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
4506
 
      ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
 
4479
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_ALTER_NOT_SUPPORTED) ||
 
4480
      ha_check_storage_engine_flag(new_db_type, HTON_BIT_ALTER_NOT_SUPPORTED))
4507
4481
  {
4508
4482
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4509
4483
    goto err;
4510
4484
  }
4511
4485
 
4512
 
  thd_proc_info(thd, "setup");
 
4486
  session->set_proc_info("setup");
4513
4487
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4514
4488
      !table->s->tmp_table) // no need to touch frm
4515
4489
  {
4527
4501
        from concurrent DDL statements.
4528
4502
      */
4529
4503
      pthread_mutex_lock(&LOCK_open);
4530
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4504
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4531
4505
      pthread_mutex_unlock(&LOCK_open);
4532
4506
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4533
4507
      /* COND_refresh will be signaled in close_thread_tables() */
4534
4508
      break;
4535
4509
    case DISABLE:
4536
4510
      pthread_mutex_lock(&LOCK_open);
4537
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4511
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4538
4512
      pthread_mutex_unlock(&LOCK_open);
4539
4513
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4540
4514
      /* COND_refresh will be signaled in close_thread_tables() */
4547
4521
    if (error == HA_ERR_WRONG_COMMAND)
4548
4522
    {
4549
4523
      error= 0;
4550
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4524
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4551
4525
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4552
4526
                          table->alias);
4553
4527
    }
4564
4538
 
4565
4539
    if (!error && (new_name != table_name || new_db != db))
4566
4540
    {
4567
 
      thd_proc_info(thd, "rename");
 
4541
      session->set_proc_info("rename");
4568
4542
      /*
4569
4543
        Then do a 'simple' rename of the table. First we need to close all
4570
4544
        instances of 'source' table.
4571
4545
      */
4572
 
      close_cached_table(thd, table);
 
4546
      close_cached_table(session, table);
4573
4547
      /*
4574
4548
        Then, we want check once again that target table does not exist.
4575
4549
        Actually the order of these two steps does not matter since
4578
4552
        we don't take this name-lock and where this order really matters.
4579
4553
        TODO: Investigate if we need this access() check at all.
4580
4554
      */
4581
 
      if (!access(new_name_buff,F_OK))
 
4555
      if (table_proto_exists(new_name)==EEXIST)
4582
4556
      {
4583
4557
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
4584
4558
        error= -1;
4600
4574
    if (error == HA_ERR_WRONG_COMMAND)
4601
4575
  {
4602
4576
      error= 0;
4603
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4577
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4604
4578
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4605
4579
                          table->alias);
4606
4580
  }
4607
4581
 
4608
4582
    if (!error)
4609
4583
    {
4610
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4611
 
      my_ok(thd);
 
4584
      write_bin_log(session, true, session->query, session->query_length);
 
4585
      session->my_ok();
4612
4586
  }
4613
4587
    else if (error > 0)
4614
4588
  {
4616
4590
      error= -1;
4617
4591
    }
4618
4592
    if (name_lock)
4619
 
      unlink_open_table(thd, name_lock, false);
 
4593
      unlink_open_table(session, name_lock, false);
4620
4594
    pthread_mutex_unlock(&LOCK_open);
4621
4595
    table_list->table= NULL;                    // For query cache
4622
4596
    return(error);
4637
4611
  */
4638
4612
  new_db_type= create_info->db_type;
4639
4613
 
4640
 
  if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
 
4614
  if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4641
4615
      goto err;
4642
4616
 
4643
 
  set_table_default_charset(thd, create_info, db);
4644
 
 
4645
 
 
4646
 
  if (thd->variables.old_alter_table
 
4617
  set_table_default_charset(session, create_info, db);
 
4618
 
 
4619
  if (session->variables.old_alter_table
4647
4620
      || (table->s->db_type() != create_info->db_type)
4648
4621
     )
4649
4622
  {
4650
4623
    if (alter_info->build_method == HA_BUILD_ONLINE)
4651
4624
    {
4652
 
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4625
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4653
4626
      goto err;
4654
4627
    }
4655
4628
    alter_info->build_method= HA_BUILD_OFFLINE;
4663
4636
    uint32_t table_changes= IS_EQUAL_YES;
4664
4637
    bool need_copy_table= true;
4665
4638
    /* Check how much the tables differ. */
4666
 
    if (compare_tables(thd, table, alter_info,
 
4639
    if (compare_tables(session, table, alter_info,
4667
4640
                       create_info, order_num,
4668
4641
                       &ha_alter_flags,
4669
4642
                       &ha_alter_info,
4686
4659
    if (new_name == table_name && new_db == db &&
4687
4660
        ha_alter_flags.is_set())
4688
4661
    {
4689
 
      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
 
4662
      Alter_info tmp_alter_info(*alter_info, session->mem_root);
4690
4663
 
4691
4664
      /*
4692
4665
        If no table rename,
4693
4666
        check if table can be altered on-line
4694
4667
      */
4695
 
      if (!(altered_table= create_altered_table(thd,
 
4668
      if (!(altered_table= create_altered_table(session,
4696
4669
                                                table,
4697
4670
                                                new_db,
4698
4671
                                                create_info,
4720
4693
      case HA_ALTER_NOT_SUPPORTED:
4721
4694
        if (alter_info->build_method == HA_BUILD_ONLINE)
4722
4695
        {
4723
 
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4724
 
          close_temporary_table(thd, altered_table, 1, 1);
 
4696
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
 
4697
          close_temporary_table(session, altered_table, 1, 1);
4725
4698
          goto err;
4726
4699
        }
4727
4700
        need_copy_table= true;
4728
4701
        break;
4729
4702
      case HA_ALTER_ERROR:
4730
4703
      default:
4731
 
        close_temporary_table(thd, altered_table, 1, 1);
 
4704
        close_temporary_table(session, altered_table, 1, 1);
4732
4705
        goto err;
4733
4706
      }
4734
4707
 
4739
4712
 
4740
4713
    if (!need_copy_table)
4741
4714
    {
4742
 
      error= mysql_fast_or_online_alter_table(thd,
 
4715
      error= mysql_fast_or_online_alter_table(session,
4743
4716
                                              table,
4744
4717
                                              altered_table,
4745
4718
                                              create_info,
4746
4719
                                              &ha_alter_info,
4747
4720
                                              &ha_alter_flags,
4748
4721
                                              alter_info->keys_onoff);
4749
 
      if (thd->lock)
 
4722
      if (session->lock)
4750
4723
      {
4751
 
        mysql_unlock_tables(thd, thd->lock);
4752
 
        thd->lock=0;
 
4724
        mysql_unlock_tables(session, session->lock);
 
4725
        session->lock=0;
4753
4726
      }
4754
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4727
      close_temporary_table(session, altered_table, 1, 1);
4755
4728
 
4756
4729
      if (error)
4757
4730
      {
4770
4743
    }
4771
4744
 
4772
4745
    if (altered_table)
4773
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4746
      close_temporary_table(session, altered_table, 1, 1);
4774
4747
  }
4775
4748
 
4776
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4777
 
           current_pid, thd->thread_id);
 
4749
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
 
4750
           (unsigned long)current_pid, session->thread_id);
4778
4751
  /* Safety fix for innodb */
4779
4752
  if (lower_case_table_names)
4780
4753
    my_casedn_str(files_charset_info, tmp_name);
4781
4754
 
4782
4755
 
4783
4756
  /* Create a temporary table with the new format */
4784
 
  if ((error= create_temporary_table(thd, table, new_db, tmp_name, 
4785
 
                                     create_info, alter_info, 
 
4757
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
 
4758
                                     create_info, alter_info,
4786
4759
                                     !strcmp(db, new_db))))
4787
4760
  {
4788
4761
    goto err;
4795
4768
    memset(&tbl, 0, sizeof(tbl));
4796
4769
    tbl.db= new_db;
4797
4770
    tbl.table_name= tbl.alias= tmp_name;
4798
 
    /* Table is in thd->temporary_tables */
4799
 
    new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
 
4771
    /* Table is in session->temporary_tables */
 
4772
    new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4800
4773
  }
4801
4774
  else
4802
4775
  {
4803
 
    char path[FN_REFLEN];
 
4776
    char tmp_path[FN_REFLEN];
4804
4777
    /* table is a normal table: Create temporary table in same directory */
4805
 
    build_table_filename(path, sizeof(path), new_db, tmp_name, "",
 
4778
    build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, "",
4806
4779
                         FN_IS_TMP);
4807
4780
    /* Open our intermediate table */
4808
 
    new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
 
4781
    new_table=open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
4809
4782
  }
4810
4783
  if (!new_table)
4811
4784
    goto err1;
4812
4785
 
4813
4786
  /* Copy the data if necessary. */
4814
 
  thd->count_cuted_fields= CHECK_FIELD_WARN;    // calc cuted fields
4815
 
  thd->cuted_fields=0L;
4816
 
  thd_proc_info(thd, "copy to tmp table");
 
4787
  session->count_cuted_fields= CHECK_FIELD_WARN;        // calc cuted fields
 
4788
  session->cuted_fields=0L;
 
4789
  session->set_proc_info("copy to tmp table");
4817
4790
  copied=deleted=0;
4818
4791
  /*
4819
4792
    We do not copy data for MERGE tables. Only the children have data.
4833
4806
  else
4834
4807
  {
4835
4808
    pthread_mutex_lock(&LOCK_open);
4836
 
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4809
    wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4837
4810
    pthread_mutex_unlock(&LOCK_open);
4838
4811
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4839
4812
                            alter_info->keys_onoff);
4840
 
    error= ha_autocommit_or_rollback(thd, 0);
4841
 
    if (end_active_trans(thd))
 
4813
    error= ha_autocommit_or_rollback(session, 0);
 
4814
    if (! session->endActiveTransaction())
4842
4815
      error= 1;
4843
4816
  }
4844
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
4817
  /* We must not ignore bad input! */;
 
4818
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
4845
4819
 
4846
4820
  if (table->s->tmp_table != NO_TMP_TABLE)
4847
4821
  {
4849
4823
    if (error)
4850
4824
      goto err1;
4851
4825
    /* Close lock if this is a transactional table */
4852
 
    if (thd->lock)
 
4826
    if (session->lock)
4853
4827
    {
4854
 
      mysql_unlock_tables(thd, thd->lock);
4855
 
      thd->lock=0;
 
4828
      mysql_unlock_tables(session, session->lock);
 
4829
      session->lock=0;
4856
4830
    }
4857
4831
    /* Remove link to old table and rename the new one */
4858
 
    close_temporary_table(thd, table, 1, 1);
 
4832
    close_temporary_table(session, table, 1, 1);
4859
4833
    /* Should pass the 'new_name' as we store table name in the cache */
4860
 
    if (rename_temporary_table(thd, new_table, new_db, new_name))
 
4834
    if (rename_temporary_table(session, new_table, new_db, new_name))
4861
4835
      goto err1;
4862
 
    /* We don't replicate alter table statement on temporary tables */
4863
 
    if (!thd->current_stmt_binlog_row_based)
4864
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4865
4836
    goto end_temporary;
4866
4837
  }
4867
4838
 
4898
4869
       call to remove name-locks from table cache and list of open table.
4899
4870
  */
4900
4871
 
4901
 
  thd_proc_info(thd, "rename result table");
4902
 
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
4903
 
           current_pid, thd->thread_id);
 
4872
  session->set_proc_info("rename result table");
 
4873
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
 
4874
           (unsigned long)current_pid, session->thread_id);
4904
4875
  if (lower_case_table_names)
4905
4876
    my_casedn_str(files_charset_info, old_name);
4906
4877
 
4907
 
  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4908
 
  close_data_files_and_morph_locks(thd, db, table_name);
 
4878
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
 
4879
  close_data_files_and_morph_locks(session, db, table_name);
4909
4880
 
4910
4881
  error=0;
4911
4882
  save_old_db_type= old_db_type;
4949
4920
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4950
4921
 
4951
4922
end_online:
4952
 
  if (thd->locked_tables && new_name == table_name && new_db == db)
 
4923
  if (session->locked_tables && new_name == table_name && new_db == db)
4953
4924
  {
4954
 
    thd->in_lock_tables= 1;
4955
 
    error= reopen_tables(thd, 1, 1);
4956
 
    thd->in_lock_tables= 0;
 
4925
    session->in_lock_tables= 1;
 
4926
    error= reopen_tables(session, 1, 1);
 
4927
    session->in_lock_tables= 0;
4957
4928
    if (error)
4958
4929
      goto err_with_placeholders;
4959
4930
  }
4960
4931
  pthread_mutex_unlock(&LOCK_open);
4961
4932
 
4962
 
  thd_proc_info(thd, "end");
4963
 
 
4964
 
  assert(!(mysql_bin_log.is_open() &&
4965
 
                thd->current_stmt_binlog_row_based &&
4966
 
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4967
 
  write_bin_log(thd, true, thd->query, thd->query_length);
4968
 
 
4969
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
 
4933
  session->set_proc_info("end");
 
4934
 
 
4935
  write_bin_log(session, true, session->query, session->query_length);
 
4936
 
 
4937
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
4970
4938
  {
4971
4939
    /*
4972
4940
      For the alter table to be properly flushed to the logs, we
4973
4941
      have to open the new table.  If not, we get a problem on server
4974
4942
      shutdown. But we do not need to attach MERGE children.
4975
4943
    */
4976
 
    char path[FN_REFLEN];
 
4944
    char table_path[FN_REFLEN];
4977
4945
    Table *t_table;
4978
 
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
4979
 
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
 
4946
    build_table_filename(table_path, sizeof(table_path), new_db, table_name, "", 0);
 
4947
    t_table= open_temporary_table(session, table_path, new_db, tmp_name, false, OTM_OPEN);
4980
4948
    if (t_table)
4981
4949
    {
4982
4950
      intern_close_table(t_table);
4983
4951
      free(t_table);
4984
4952
    }
4985
4953
    else
4986
 
      sql_print_warning(_("Could not open table %s.%s after rename\n"),
4987
 
                        new_db,table_name);
 
4954
      errmsg_printf(ERRMSG_LVL_WARN,
 
4955
                    _("Could not open table %s.%s after rename\n"),
 
4956
                    new_db,table_name);
4988
4957
    ha_flush_logs(old_db_type);
4989
4958
  }
4990
4959
  table_list->table=0;                          // For query cache
4991
4960
 
4992
 
  if (thd->locked_tables && (new_name != table_name || new_db != db))
 
4961
  if (session->locked_tables && (new_name != table_name || new_db != db))
4993
4962
  {
4994
4963
    /*
4995
4964
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
4998
4967
      LOCK TABLES we can rely on close_thread_tables() doing this job.
4999
4968
    */
5000
4969
    pthread_mutex_lock(&LOCK_open);
5001
 
    unlink_open_table(thd, table, false);
5002
 
    unlink_open_table(thd, name_lock, false);
 
4970
    unlink_open_table(session, table, false);
 
4971
    unlink_open_table(session, name_lock, false);
5003
4972
    pthread_mutex_unlock(&LOCK_open);
5004
4973
  }
5005
4974
 
5006
4975
end_temporary:
5007
 
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5008
 
           (ulong) (copied + deleted), (ulong) deleted,
5009
 
           (ulong) thd->cuted_fields);
5010
 
  my_ok(thd, copied + deleted, 0L, tmp_name);
5011
 
  thd->some_tables_deleted=0;
5012
 
  return(false);
 
4976
  /*
 
4977
   * Field::store() may have called my_error().  If this is 
 
4978
   * the case, we must not send an ok packet, since 
 
4979
   * Diagnostics_area::is_set() will fail an assert.
 
4980
   */
 
4981
  if (! session->is_error())
 
4982
  {
 
4983
    snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 
4984
            (ulong) (copied + deleted), (ulong) deleted,
 
4985
            (ulong) session->cuted_fields);
 
4986
    session->my_ok(copied + deleted, 0L, tmp_name);
 
4987
    session->some_tables_deleted=0;
 
4988
    return false;
 
4989
  }
 
4990
  else
 
4991
  {
 
4992
    /* my_error() was called.  Return true (which means error...) */
 
4993
    return true;
 
4994
  }
5013
4995
 
5014
4996
err1:
5015
4997
  if (new_table)
5016
4998
  {
5017
4999
    /* close_temporary_table() frees the new_table pointer. */
5018
 
    close_temporary_table(thd, new_table, 1, 1);
 
5000
    close_temporary_table(session, new_table, 1, 1);
5019
5001
  }
5020
5002
  else
5021
5003
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5027
5009
    the table to be altered isn't empty.
5028
5010
    Report error here.
5029
5011
  */
5030
 
  if (alter_info->error_if_not_empty && thd->row_count)
 
5012
  if (alter_info->error_if_not_empty && session->row_count)
5031
5013
  {
5032
5014
    const char *f_val= 0;
5033
5015
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
5034
5016
    switch (alter_info->datetime_field->sql_type)
5035
5017
    {
5036
 
      case DRIZZLE_TYPE_NEWDATE:
 
5018
      case DRIZZLE_TYPE_DATE:
5037
5019
        f_val= "0000-00-00";
5038
5020
        t_type= DRIZZLE_TIMESTAMP_DATE;
5039
5021
        break;
5045
5027
        /* Shouldn't get here. */
5046
5028
        assert(0);
5047
5029
    }
5048
 
    bool save_abort_on_warning= thd->abort_on_warning;
5049
 
    thd->abort_on_warning= true;
5050
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
5030
    bool save_abort_on_warning= session->abort_on_warning;
 
5031
    session->abort_on_warning= true;
 
5032
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5051
5033
                                 f_val, strlength(f_val), t_type,
5052
5034
                                 alter_info->datetime_field->field_name);
5053
 
    thd->abort_on_warning= save_abort_on_warning;
 
5035
    session->abort_on_warning= save_abort_on_warning;
5054
5036
  }
5055
5037
  if (name_lock)
5056
5038
  {
5057
5039
    pthread_mutex_lock(&LOCK_open);
5058
 
    unlink_open_table(thd, name_lock, false);
 
5040
    unlink_open_table(session, name_lock, false);
5059
5041
    pthread_mutex_unlock(&LOCK_open);
5060
5042
  }
5061
5043
  return(true);
5066
5048
    being altered. To be safe under LOCK TABLES we should remove placeholders
5067
5049
    from list of open tables list and table cache.
5068
5050
  */
5069
 
  unlink_open_table(thd, table, false);
 
5051
  unlink_open_table(session, table, false);
5070
5052
  if (name_lock)
5071
 
    unlink_open_table(thd, name_lock, false);
 
5053
    unlink_open_table(session, name_lock, false);
5072
5054
  pthread_mutex_unlock(&LOCK_open);
5073
5055
  return(true);
5074
5056
}
5087
5069
  int error;
5088
5070
  Copy_field *copy,*copy_end;
5089
5071
  ulong found_count,delete_count;
5090
 
  THD *thd= current_thd;
 
5072
  Session *session= current_session;
5091
5073
  uint32_t length= 0;
5092
5074
  SORT_FIELD *sortorder;
5093
5075
  READ_RECORD info;
5102
5084
  /*
5103
5085
    Turn off recovery logging since rollback of an alter table is to
5104
5086
    delete the new table so there is no need to log the changes to it.
5105
 
    
 
5087
 
5106
5088
    This needs to be done before external_lock
5107
5089
  */
5108
 
  error= ha_enable_transaction(thd, false);
 
5090
  error= ha_enable_transaction(session, false);
5109
5091
  if (error)
5110
5092
    return(-1);
5111
 
  
 
5093
 
5112
5094
  if (!(copy= new Copy_field[to->s->fields]))
5113
5095
    return(-1);                         /* purecov: inspected */
5114
5096
 
5115
 
  if (to->file->ha_external_lock(thd, F_WRLCK))
 
5097
  if (to->file->ha_external_lock(session, F_WRLCK))
5116
5098
    return(-1);
5117
5099
 
5118
5100
  /* We need external lock before we can disable/enable keys */
5119
5101
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5120
5102
 
5121
5103
  /* We can abort alter table for any table type */
5122
 
  thd->abort_on_warning= !ignore;
 
5104
  session->abort_on_warning= !ignore;
5123
5105
 
5124
5106
  from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5125
5107
  to->file->ha_start_bulk_insert(from->file->stats.records);
5126
5108
 
5127
 
  save_sql_mode= thd->variables.sql_mode;
 
5109
  save_sql_mode= session->variables.sql_mode;
5128
5110
 
5129
5111
  List_iterator<Create_field> it(create);
5130
5112
  Create_field *def;
5149
5131
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5150
5132
    {
5151
5133
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
5152
 
      snprintf(warn_buff, sizeof(warn_buff), 
 
5134
      snprintf(warn_buff, sizeof(warn_buff),
5153
5135
               _("order_st BY ignored because there is a user-defined clustered "
5154
5136
                 "index in the table '%-.192s'"),
5155
5137
               from->s->table_name.str);
5156
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
5138
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5157
5139
                   warn_buff);
5158
5140
    }
5159
5141
    else
5160
5142
    {
5161
 
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5162
 
                                                MYF(MY_FAE | MY_ZEROFILL));
 
5143
      from->sort.io_cache= new IO_CACHE;
 
5144
      memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
 
5145
 
5163
5146
      memset(&tables, 0, sizeof(tables));
5164
5147
      tables.table= from;
5165
5148
      tables.alias= tables.table_name= from->s->table_name.str;
5166
5149
      tables.db= from->s->db.str;
5167
5150
      error= 1;
5168
5151
 
5169
 
      if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5170
 
          setup_order(thd, thd->lex->select_lex.ref_pointer_array,
 
5152
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
 
5153
          setup_order(session, session->lex->select_lex.ref_pointer_array,
5171
5154
                      &tables, fields, all_fields, order) ||
5172
5155
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5173
 
          (from->sort.found_records= filesort(thd, from, sortorder, length,
 
5156
          (from->sort.found_records= filesort(session, from, sortorder, length,
5174
5157
                                              (SQL_SELECT *) 0, HA_POS_ERROR,
5175
5158
                                              1, &examined_rows)) ==
5176
5159
          HA_POS_ERROR)
5180
5163
 
5181
5164
  /* Tell handler that we have values for all columns in the to table */
5182
5165
  to->use_all_columns();
5183
 
  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
 
5166
  init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
5184
5167
  if (ignore)
5185
5168
    to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5186
 
  thd->row_count= 0;
 
5169
  session->row_count= 0;
5187
5170
  restore_record(to, s->default_values);        // Create empty record
5188
5171
  while (!(error=info.read_record(&info)))
5189
5172
  {
5190
 
    if (thd->killed)
 
5173
    if (session->killed)
5191
5174
    {
5192
 
      thd->send_kill_message();
 
5175
      session->send_kill_message();
5193
5176
      error= 1;
5194
5177
      break;
5195
5178
    }
5196
 
    thd->row_count++;
 
5179
    session->row_count++;
5197
5180
    /* Return error if source table isn't empty. */
5198
5181
    if (error_if_not_empty)
5199
5182
    {
5207
5190
      else
5208
5191
        to->next_number_field->reset();
5209
5192
    }
5210
 
    
 
5193
 
5211
5194
    for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
5212
5195
    {
5213
5196
      copy_ptr->do_copy(copy_ptr);
5214
5197
    }
5215
5198
    prev_insert_id= to->file->next_insert_id;
 
5199
    update_virtual_fields_marked_for_write(to, false);
5216
5200
    error=to->file->ha_write_row(to->record[0]);
5217
5201
    to->auto_increment_field_not_null= false;
5218
5202
    if (error)
5255
5239
  }
5256
5240
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
5257
5241
 
5258
 
  if (ha_enable_transaction(thd, true))
 
5242
  if (ha_enable_transaction(session, true))
5259
5243
  {
5260
5244
    error= 1;
5261
5245
    goto err;
5265
5249
    Ensure that the new table is saved properly to disk so that we
5266
5250
    can do a rename
5267
5251
  */
5268
 
  if (ha_autocommit_or_rollback(thd, 0))
 
5252
  if (ha_autocommit_or_rollback(session, 0))
5269
5253
    error=1;
5270
 
  if (end_active_trans(thd))
 
5254
  if (! session->endActiveTransaction())
5271
5255
    error=1;
5272
5256
 
5273
5257
 err:
5274
 
  thd->variables.sql_mode= save_sql_mode;
5275
 
  thd->abort_on_warning= 0;
 
5258
  session->variables.sql_mode= save_sql_mode;
 
5259
  session->abort_on_warning= 0;
5276
5260
  free_io_cache(from);
5277
5261
  *copied= found_count;
5278
5262
  *deleted=delete_count;
5279
5263
  to->file->ha_release_auto_increment();
5280
 
  if (to->file->ha_external_lock(thd,F_UNLCK))
 
5264
  if (to->file->ha_external_lock(session,F_UNLCK))
5281
5265
    error=1;
5282
5266
  return(error > 0 ? -1 : 0);
5283
5267
}
5288
5272
 
5289
5273
  SYNOPSIS
5290
5274
    mysql_recreate_table()
5291
 
    thd                 Thread handler
 
5275
    session                     Thread handler
5292
5276
    tables              Tables to recreate
5293
5277
 
5294
5278
 RETURN
5295
5279
    Like mysql_alter_table().
5296
5280
*/
5297
 
bool mysql_recreate_table(THD *thd, TableList *table_list)
 
5281
bool mysql_recreate_table(Session *session, TableList *table_list)
5298
5282
{
5299
5283
  HA_CREATE_INFO create_info;
5300
5284
  Alter_info alter_info;
5311
5295
  create_info.default_table_charset=default_charset_info;
5312
5296
  /* Force alter table to recreate table */
5313
5297
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5314
 
  return(mysql_alter_table(thd, NULL, NULL, &create_info,
 
5298
  return(mysql_alter_table(session, NULL, NULL, &create_info,
5315
5299
                                table_list, &alter_info, 0,
5316
5300
                                (order_st *) 0, 0));
5317
5301
}
5318
5302
 
5319
5303
 
5320
 
bool mysql_checksum_table(THD *thd, TableList *tables,
 
5304
bool mysql_checksum_table(Session *session, TableList *tables,
5321
5305
                          HA_CHECK_OPT *check_opt)
5322
5306
{
5323
5307
  TableList *table;
5324
5308
  List<Item> field_list;
5325
5309
  Item *item;
5326
 
  Protocol *protocol= thd->protocol;
 
5310
  Protocol *protocol= session->protocol;
5327
5311
 
5328
5312
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5329
5313
  item->maybe_null= 1;
5340
5324
    char table_name[NAME_LEN*2+2];
5341
5325
    Table *t;
5342
5326
 
5343
 
    strxmov(table_name, table->db ,".", table->table_name, NULL);
 
5327
    sprintf(table_name,"%s.%s",table->db,table->table_name);
5344
5328
 
5345
 
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5346
 
    thd->clear_error();                 // these errors shouldn't get client
 
5329
    t= table->table= open_n_lock_single_table(session, table, TL_READ);
 
5330
    session->clear_error();                     // these errors shouldn't get client
5347
5331
 
5348
5332
    protocol->prepare_for_resend();
5349
5333
    protocol->store(table_name, system_charset_info);
5352
5336
    {
5353
5337
      /* Table didn't exist */
5354
5338
      protocol->store_null();
5355
 
      thd->clear_error();
 
5339
      session->clear_error();
5356
5340
    }
5357
5341
    else
5358
5342
    {
5415
5399
          t->file->ha_rnd_end();
5416
5400
        }
5417
5401
      }
5418
 
      thd->clear_error();
5419
 
      close_thread_tables(thd);
 
5402
      session->clear_error();
 
5403
      close_thread_tables(session);
5420
5404
      table->table=0;                           // For query cache
5421
5405
    }
5422
5406
    if (protocol->write())
5423
5407
      goto err;
5424
5408
  }
5425
5409
 
5426
 
  my_eof(thd);
 
5410
  session->my_eof();
5427
5411
  return(false);
5428
5412
 
5429
5413
 err:
5430
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
5414
  close_thread_tables(session);                 // Shouldn't be needed
5431
5415
  if (table)
5432
5416
    table->table=0;
5433
5417
  return(true);
5434
5418
}
5435
5419
 
5436
 
static bool check_engine(THD *thd, const char *table_name,
 
5420
static bool check_engine(Session *session, const char *table_name,
5437
5421
                         HA_CREATE_INFO *create_info)
5438
5422
{
5439
 
  handlerton **new_engine= &create_info->db_type;
5440
 
  handlerton *req_engine= *new_engine;
 
5423
  StorageEngine **new_engine= &create_info->db_type;
 
5424
  StorageEngine *req_engine= *new_engine;
5441
5425
  bool no_substitution= 1;
5442
 
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
 
5426
  if (!(*new_engine= ha_checktype(session, ha_legacy_type(req_engine),
5443
5427
                                  no_substitution, 1)))
5444
5428
    return true;
5445
5429
 
5446
5430
  if (req_engine && req_engine != *new_engine)
5447
5431
  {
5448
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5432
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5449
5433
                       ER_WARN_USING_OTHER_HANDLER,
5450
5434
                       ER(ER_WARN_USING_OTHER_HANDLER),
5451
5435
                       ha_resolve_storage_engine_name(*new_engine),
5452
5436
                       table_name);
5453
5437
  }
5454
5438
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5455
 
      ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
 
5439
      ha_check_storage_engine_flag(*new_engine, HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5456
5440
  {
5457
5441
    if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5458
5442
    {