~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2009-04-27 14:36:40 UTC
  • Revision ID: brian@gaz-20090427143640-f6zjmtt9vm55qgm2
Patch on show processlist from  davi@apache.org

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