~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Toru Maesaka
  • Date: 2008-12-17 07:16:37 UTC
  • mto: (685.1.40 devel) (713.1.5 devel)
  • mto: This revision was merged to the branch mainline in revision 713.
  • Revision ID: dev@torum.net-20081217071637-7j9040w7lpms77r2
Removed my_time() and added error checking

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/replicator.h>
 
31
#include <drizzled/lock.h>
 
32
#include <drizzled/unireg.h>
 
33
#include <drizzled/item/int.h>
 
34
#include <drizzled/item/empty_string.h>
 
35
 
 
36
using namespace std;
 
37
 
 
38
extern HASH lock_db_cache;
23
39
 
24
40
int creating_table= 0;        // How many mysql_create_table are running
25
41
 
26
 
const char *primary_key_name="PRIMARY";
 
42
 
 
43
bool is_primary_key(KEY *key_info)
 
44
{
 
45
  static const char * primary_key_name="PRIMARY";
 
46
  return (strcmp(key_info->name, primary_key_name)==0);
 
47
}
 
48
 
 
49
const char* is_primary_key_name(const char* key_name)
 
50
{
 
51
  static const char * primary_key_name="PRIMARY";
 
52
  if (strcmp(key_name, primary_key_name)==0)
 
53
    return key_name;
 
54
  else
 
55
    return NULL;
 
56
}
27
57
 
28
58
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
59
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
34
64
                                    enum enum_enable_or_disable keys_onoff,
35
65
                                    bool error_if_not_empty);
36
66
 
37
 
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
38
 
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
 
67
static bool prepare_blob_field(Session *session, Create_field *sql_field);
 
68
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
39
69
static int
40
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
70
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
41
71
                           Alter_info *alter_info,
42
72
                           bool tmp_table,
43
73
                               uint32_t *db_options,
44
74
                               handler *file, KEY **key_info_buffer,
45
75
                               uint32_t *key_count, int select_field_count);
46
76
static bool
47
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
77
mysql_prepare_alter_table(Session *session, Table *table,
48
78
                          HA_CREATE_INFO *create_info,
49
79
                          Alter_info *alter_info);
50
80
 
65
95
  uint32_t errors;
66
96
  uint32_t res;
67
97
 
68
 
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
 
98
  if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
69
99
  {
70
100
    /* Temporary table name. */
71
 
    res= (my_stpncpy(to, from, to_length) - to);
 
101
    res= strlen(strncpy(to, from, to_length));
72
102
  }
73
103
  else
74
104
  {
76
106
                    system_charset_info,  to, to_length, &errors);
77
107
    if (errors) // Old 5.0 name
78
108
    {
79
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NULL) -
80
 
            to);
 
109
      strcpy(to, MYSQL50_TABLE_NAME_PREFIX);
 
110
      strncat(to, from, to_length-MYSQL50_TABLE_NAME_PREFIX_LENGTH-1);
 
111
      res= strlen(to);
81
112
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
82
113
    }
83
114
  }
98
129
  RETURN
99
130
    File name length.
100
131
*/
101
 
 
102
132
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
103
133
{
104
134
  uint32_t errors, length;
105
135
 
106
136
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
107
137
                                 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)));
 
138
    return((uint) (strncpy(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
 
139
                           to_length-1) -
 
140
                           (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
111
141
  length= strconvert(system_charset_info, from,
112
142
                     &my_charset_filename, to, to_length, &errors);
113
143
  if (check_if_legal_tablename(to) &&
121
151
 
122
152
 
123
153
/*
124
 
  Creates path to a file: mysql_data_dir/db/table.ext
 
154
  Creates path to a file: drizzle_data_dir/db/table.ext
125
155
 
126
156
  SYNOPSIS
127
157
   build_table_filename()
137
167
  NOTES
138
168
 
139
169
    Uses database and table name, and extension to create
140
 
    a file name in mysql_data_dir. Database and table
 
170
    a file name in drizzle_data_dir. Database and table
141
171
    names are converted from system_charset_info into "fscs".
142
172
    Unless flags indicate a temporary table name.
143
173
    'db' is always converted.
150
180
    build_tmptable_filename() for them.
151
181
 
152
182
  RETURN
153
 
    path length
 
183
    path length on success, 0 on failure
154
184
*/
155
185
 
156
186
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
157
187
                          const char *table_name, const char *ext, uint32_t flags)
158
188
{
 
189
  string table_path;
159
190
  char dbbuff[FN_REFLEN];
160
191
  char tbbuff[FN_REFLEN];
 
192
  int rootdir_len= strlen(FN_ROOTDIR);
161
193
 
162
194
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
 
    my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
 
195
    strncpy(tbbuff, table_name, sizeof(tbbuff));
164
196
  else
165
197
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
166
198
 
167
199
  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);
 
200
  table_path= drizzle_data_home;
 
201
  int without_rootdir= table_path.length()-rootdir_len;
 
202
 
 
203
  /* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
 
204
  if (without_rootdir >= 0)
 
205
  {
 
206
    char *tmp= (char*)table_path.c_str()+without_rootdir;
 
207
    if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
 
208
      table_path.append(FN_ROOTDIR);
 
209
  }
 
210
 
 
211
  table_path.append(dbbuff);
 
212
  table_path.append(FN_ROOTDIR);
177
213
#ifdef USE_SYMDIR
178
 
  unpack_dirname(buff, buff);
179
 
  pos= strend(buff);
 
214
  table_path.clear();
180
215
#endif
181
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
182
 
 
183
 
  return(pos - buff);
 
216
  table_path.append(tbbuff);
 
217
  table_path.append(ext);
 
218
 
 
219
  if (bufflen < table_path.length())
 
220
    return 0;
 
221
 
 
222
  strcpy(buff, table_path.c_str());
 
223
  return table_path.length();
184
224
}
185
225
 
186
226
 
187
227
/*
188
 
  Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
 
228
  Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
189
229
 
190
230
  SYNOPSIS
191
231
   build_tmptable_filename()
192
 
     thd                        The thread handle.
 
232
     session                    The thread handle.
193
233
     buff                       Where to write result in my_charset_filename.
194
234
     bufflen                    buff size
195
235
 
196
236
  NOTES
197
237
 
198
238
    Uses current_pid, thread_id, and tmp_table counter to create
199
 
    a file name in mysql_tmpdir.
 
239
    a file name in drizzle_tmpdir.
200
240
 
201
241
  RETURN
202
 
    path length
 
242
    path length on success, 0 on failure
203
243
*/
204
244
 
205
 
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
245
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
206
246
{
 
247
  uint32_t length;
 
248
  ostringstream path_str, post_tmpdir_str;
 
249
  string tmp;
207
250
 
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);
 
251
  path_str << drizzle_tmpdir;
 
252
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
 
253
  post_tmpdir_str << session->thread_id << session->tmp_table++ << reg_ext;
 
254
  tmp= post_tmpdir_str.str();
212
255
 
213
256
  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);
 
257
    transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
 
258
 
 
259
  path_str << tmp;
 
260
 
 
261
  if (bufflen < path_str.str().length())
 
262
    length= 0;
 
263
  else
 
264
    length= unpack_filename(buff, path_str.str().c_str());
 
265
 
 
266
  return length;
221
267
}
222
268
 
223
269
/*
224
270
  SYNOPSIS
225
271
    write_bin_log()
226
 
    thd                           Thread object
 
272
    session                           Thread object
227
273
    clear_error                   is clear_error to be called
228
274
    query                         Query to log
229
275
    query_length                  Length of query
236
282
    file
237
283
*/
238
284
 
239
 
void write_bin_log(THD *thd, bool clear_error,
240
 
                   char const *query, ulong query_length)
 
285
void write_bin_log(Session *session, bool,
 
286
                   char const *query, size_t query_length)
241
287
{
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
 
  }
 
288
  (void)replicator_statement(session, query, query_length);
249
289
}
250
290
 
251
291
 
254
294
 
255
295
  SYNOPSIS
256
296
   mysql_rm_table()
257
 
   thd                  Thread handle
 
297
   session                      Thread handle
258
298
   tables               List of tables to delete
259
299
   if_exists            If 1, don't give error if one table doesn't exists
260
300
 
273
313
 
274
314
*/
275
315
 
276
 
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
 
316
bool mysql_rm_table(Session *session,TableList *tables, bool if_exists, bool drop_temporary)
277
317
{
278
318
  bool error, need_start_waiting= false;
279
319
 
280
320
  if (tables && tables->schema_table)
281
321
  {
282
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
322
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
283
323
    return(true);
284
324
  }
285
325
 
287
327
 
288
328
  if (!drop_temporary)
289
329
  {
290
 
    if (!thd->locked_tables &&
291
 
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
330
    if (!session->locked_tables &&
 
331
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
292
332
      return(true);
293
333
  }
294
334
 
297
337
    LOCK_open during wait_if_global_read_lock(), other threads could not
298
338
    close their tables. This would make a pretty deadlock.
299
339
  */
300
 
  error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
 
340
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0);
301
341
 
302
342
  if (need_start_waiting)
303
 
    start_waiting_global_read_lock(thd);
 
343
    start_waiting_global_read_lock(session);
304
344
 
305
345
  if (error)
306
346
    return(true);
307
 
  my_ok(thd);
 
347
  my_ok(session);
308
348
  return(false);
309
349
}
310
350
 
313
353
 
314
354
  SYNOPSIS
315
355
    mysql_rm_table_part2()
316
 
    thd                 Thread handler
 
356
    session                     Thread handler
317
357
    tables              Tables to drop
318
358
    if_exists           If set, don't give an error if table doesn't exists.
319
359
                        In this case we give an warning of level 'NOTE'
320
360
    drop_temporary      Only drop temporary tables
321
361
    drop_view           Allow to delete VIEW .frm
322
362
    dont_log_query      Don't write query to log files. This will also not
323
 
                        generate warnings if the handler files doesn't exists  
 
363
                        generate warnings if the handler files doesn't exists
324
364
 
325
365
  TODO:
326
366
    When logging to the binary log, we should log
338
378
   -1   Thread was killed
339
379
*/
340
380
 
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)
 
381
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
 
382
                         bool drop_temporary, bool dont_log_query)
344
383
{
345
384
  TableList *table;
346
385
  char path[FN_REFLEN], *alias;
351
390
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
352
391
  String built_query;
353
392
 
354
 
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
393
  if (!dont_log_query)
355
394
  {
356
395
    built_query.set_charset(system_charset_info);
357
396
    if (if_exists)
360
399
      built_query.append("DROP Table ");
361
400
  }
362
401
 
363
 
  mysql_ha_rm_tables(thd, tables, false);
 
402
  mysql_ha_rm_tables(session, tables, false);
364
403
 
365
404
  pthread_mutex_lock(&LOCK_open);
366
405
 
378
417
      table->db_type= share->db_type();
379
418
  }
380
419
 
381
 
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
 
420
  if (!drop_temporary && lock_table_names_exclusively(session, tables))
382
421
  {
383
422
    pthread_mutex_unlock(&LOCK_open);
384
423
    return(1);
385
424
  }
386
425
 
387
426
  /* Don't give warnings for not found errors, as we already generate notes */
388
 
  thd->no_warnings_for_error= 1;
 
427
  session->no_warnings_for_error= 1;
389
428
 
390
429
  for (table= tables; table; table= table->next_local)
391
430
  {
392
431
    char *db=table->db;
393
432
    handlerton *table_type;
394
 
    enum legacy_db_type frm_db_type;
395
 
 
396
 
 
397
 
    error= drop_temporary_table(thd, table);
 
433
 
 
434
    error= drop_temporary_table(session, table);
398
435
 
399
436
    switch (error) {
400
437
    case  0:
402
439
      tmp_table_deleted= 1;
403
440
      continue;
404
441
    case -1:
405
 
      assert(thd->in_sub_stmt);
406
442
      error= 1;
407
443
      goto err_with_placeholders;
408
444
    default:
416
452
      being built.  The string always end in a comma and the comma
417
453
      will be chopped off before being written to the binary log.
418
454
      */
419
 
    if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
455
    if (!dont_log_query)
420
456
    {
421
457
      non_temp_tables_count++;
422
458
      /*
423
459
        Don't write the database name if it is the current one (or if
424
 
        thd->db is NULL).
 
460
        session->db is NULL).
425
461
      */
426
462
      built_query.append("`");
427
 
      if (thd->db == NULL || strcmp(db,thd->db) != 0)
 
463
      if (session->db == NULL || strcmp(db,session->db) != 0)
428
464
      {
429
465
        built_query.append(db);
430
466
        built_query.append("`.`");
438
474
    if (!drop_temporary)
439
475
    {
440
476
      Table *locked_table;
441
 
      abort_locked_tables(thd, db, table->table_name);
442
 
      remove_table_from_cache(thd, db, table->table_name,
 
477
      abort_locked_tables(session, db, table->table_name);
 
478
      remove_table_from_cache(session, db, table->table_name,
443
479
                              RTFC_WAIT_OTHER_THREAD_FLAG |
444
480
                              RTFC_CHECK_KILLED_FLAG);
445
481
      /*
446
482
        If the table was used in lock tables, remember it so that
447
483
        unlock_table_names can free it
448
484
      */
449
 
      if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
 
485
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
450
486
        table->table= locked_table;
451
487
 
452
 
      if (thd->killed)
 
488
      if (session->killed)
453
489
      {
454
490
        error= -1;
455
491
        goto err_with_placeholders;
461
497
                                        FN_IS_TMP : 0);
462
498
    }
463
499
    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)))
 
500
        ((table_type == NULL && (access(path, F_OK))))
 
501
        )
466
502
    {
467
503
      // Table was not found on disk and table can't be created from engine
468
504
      if (if_exists)
469
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
505
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
470
506
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
471
507
                            table->table_name);
472
508
      else
475
511
    else
476
512
    {
477
513
      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
514
      // Remove extension for delete
484
515
      *(end= path + path_length - reg_ext_length)= '\0';
485
 
      error= ha_delete_table(thd, table_type, path, db, table->table_name,
 
516
      error= ha_delete_table(session, path, db, table->table_name,
486
517
                             !dont_log_query);
487
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
488
 
          (if_exists || table_type == NULL))
 
518
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
 
519
          if_exists)
489
520
      {
490
521
        error= 0;
491
 
        thd->clear_error();
 
522
        session->clear_error();
492
523
      }
493
524
      if (error == HA_ERR_ROW_IS_REFERENCED)
494
525
      {
498
529
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
499
530
      {
500
531
        int new_error;
 
532
 
 
533
        /* for some weird-ass reason, we ignore the return code here
 
534
           and things work. */
 
535
        delete_table_proto_file(path);
 
536
 
501
537
        /* Delete the table definition file */
502
 
        my_stpcpy(end,reg_ext);
 
538
        strcpy(end,reg_ext);
503
539
        if (!(new_error=my_delete(path,MYF(MY_WME))))
504
540
        {
505
541
          some_tables_deleted=1;
520
556
    on the table name.
521
557
  */
522
558
  pthread_mutex_unlock(&LOCK_open);
523
 
  thd->thread_specific_used|= tmp_table_deleted;
 
559
  session->thread_specific_used|= tmp_table_deleted;
524
560
  error= 0;
525
561
  if (wrong_tables.length())
526
562
  {
538
574
  {
539
575
    if (!dont_log_query)
540
576
    {
541
 
      if (!thd->current_stmt_binlog_row_based ||
542
 
          (non_temp_tables_count > 0 && !tmp_table_deleted))
 
577
      if ((non_temp_tables_count > 0 && !tmp_table_deleted))
543
578
      {
544
579
        /*
545
580
          In this case, we are either using statement-based
548
583
          tables).  In this case, we can write the original query into
549
584
          the binary log.
550
585
         */
551
 
        write_bin_log(thd, !error, thd->query, thd->query_length);
 
586
        write_bin_log(session, !error, session->query, session->query_length);
552
587
      }
553
 
      else if (thd->current_stmt_binlog_row_based &&
554
 
               non_temp_tables_count > 0 &&
 
588
      else if (non_temp_tables_count > 0 &&
555
589
               tmp_table_deleted)
556
590
      {
557
591
        /*
568
602
        */
569
603
        built_query.chop();                  // Chop of the last comma
570
604
        built_query.append(" /* generated by server */");
571
 
        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
 
605
        write_bin_log(session, !error, built_query.ptr(), built_query.length());
572
606
      }
573
607
      /*
574
608
        The remaining cases are:
582
616
  }
583
617
  pthread_mutex_lock(&LOCK_open);
584
618
err_with_placeholders:
585
 
  unlock_table_names(thd, tables, (TableList*) 0);
 
619
  unlock_table_names(session, tables, (TableList*) 0);
586
620
  pthread_mutex_unlock(&LOCK_open);
587
 
  thd->no_warnings_for_error= 0;
 
621
  session->no_warnings_for_error= 0;
588
622
  return(error);
589
623
}
590
624
 
604
638
    != 0        Error
605
639
*/
606
640
 
607
 
bool quick_rm_table(handlerton *base,const char *db,
 
641
bool quick_rm_table(handlerton *base __attribute__((unused)),const char *db,
608
642
                    const char *table_name, uint32_t flags)
609
643
{
610
644
  char path[FN_REFLEN];
614
648
                                         db, table_name, reg_ext, flags);
615
649
  if (my_delete(path,MYF(0)))
616
650
    error= 1; /* purecov: inspected */
 
651
 
617
652
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
618
 
  return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
 
653
 
 
654
  error|= delete_table_proto_file(path);
 
655
 
 
656
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
619
657
              error);
620
658
}
621
659
 
635
673
static int sort_keys(KEY *a, KEY *b)
636
674
{
637
675
  ulong a_flags= a->flags, b_flags= b->flags;
638
 
  
 
676
 
639
677
  if (a_flags & HA_NOSAME)
640
678
  {
641
679
    if (!(b_flags & HA_NOSAME))
645
683
      /* Sort NOT NULL keys before other keys */
646
684
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
647
685
    }
648
 
    if (a->name == primary_key_name)
 
686
    if (is_primary_key(a))
649
687
      return -1;
650
 
    if (b->name == primary_key_name)
 
688
    if (is_primary_key(b))
651
689
      return 1;
652
690
    /* Sort keys don't containing partial segments before others */
653
691
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
691
729
  TYPELIB tmp= *typelib;
692
730
  const char **cur_value= typelib->type_names;
693
731
  unsigned int *cur_length= typelib->type_lengths;
694
 
  *dup_val_count= 0;  
695
 
  
 
732
  *dup_val_count= 0;
 
733
 
696
734
  for ( ; tmp.count > 1; cur_value++, cur_length++)
697
735
  {
698
736
    tmp.type_names++;
762
800
   1    Error
763
801
*/
764
802
 
765
 
int prepare_create_field(Create_field *sql_field, 
 
803
int prepare_create_field(Create_field *sql_field,
766
804
                         uint32_t *blob_columns,
767
805
                         int *timestamps, int *timestamps_with_niladic,
768
806
                         int64_t table_flags __attribute__((unused)))
802
840
                                     sql_field->charset, &dup_val_count))
803
841
      return(1);
804
842
    break;
805
 
  case DRIZZLE_TYPE_NEWDATE:  // Rest of string types
 
843
  case DRIZZLE_TYPE_DATE:  // Rest of string types
806
844
  case DRIZZLE_TYPE_TIME:
807
845
  case DRIZZLE_TYPE_DATETIME:
808
846
  case DRIZZLE_TYPE_NULL:
840
878
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
841
879
    break;
842
880
  }
843
 
  if (!(sql_field->flags & NOT_NULL_FLAG))
 
881
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
 
882
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
844
883
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
845
884
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
846
885
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
852
891
 
853
892
  SYNOPSIS
854
893
    mysql_prepare_create_table()
855
 
      thd                       Thread object.
 
894
      session                       Thread object.
856
895
      create_info               Create information (like MAX_ROWS).
857
896
      alter_info                List of columns and indexes to create
858
897
      tmp_table                 If a temporary table is to be created.
874
913
*/
875
914
 
876
915
static int
877
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
916
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
878
917
                           Alter_info *alter_info,
879
918
                           bool tmp_table,
880
919
                               uint32_t *db_options,
926
965
                                                    MY_CS_BINSORT,MYF(0))))
927
966
    {
928
967
      char tmp[64];
929
 
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
930
 
              STRING_WITH_LEN("_bin"));
 
968
      char *tmp_pos= tmp;
 
969
      strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
 
970
      tmp_pos+= strlen(tmp);
 
971
      strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
931
972
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
932
973
      return(true);
933
974
    }
936
977
      Convert the default value from client character
937
978
      set into the column character set if necessary.
938
979
    */
939
 
    if (sql_field->def && 
 
980
    if (sql_field->def &&
940
981
        save_cs != sql_field->def->collation.collation &&
941
982
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
942
983
    {
978
1019
          occupied memory at the same time when we free this
979
1020
          sql_field -- at the end of execution.
980
1021
        */
981
 
        interval= sql_field->interval= typelib(thd->mem_root,
 
1022
        interval= sql_field->interval= typelib(session->mem_root,
982
1023
                                               sql_field->interval_list);
983
1024
        List_iterator<String> int_it(sql_field->interval_list);
984
1025
        String conv, *tmp;
985
1026
        char comma_buf[4];
986
1027
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
987
 
                                          (unsigned char*) comma_buf + 
 
1028
                                          (unsigned char*) comma_buf +
988
1029
                                          sizeof(comma_buf));
989
1030
        assert(comma_length > 0);
990
1031
        for (uint32_t i= 0; (tmp= int_it++); i++)
995
1036
          {
996
1037
            uint32_t cnv_errs;
997
1038
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
998
 
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
 
1039
            interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
999
1040
                                                  conv.length());
1000
1041
            interval->type_lengths[i]= conv.length();
1001
1042
          }
1025
1066
            }
1026
1067
 
1027
1068
            /* else, the defaults yield the correct length for NULLs. */
1028
 
          } 
 
1069
          }
1029
1070
          else /* not NULL */
1030
1071
          {
1031
1072
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
1043
1084
    }
1044
1085
 
1045
1086
    sql_field->create_length_to_internal_length();
1046
 
    if (prepare_blob_field(thd, sql_field))
 
1087
    if (prepare_blob_field(session, sql_field))
1047
1088
      return(true);
1048
1089
 
1049
1090
    if (!(sql_field->flags & NOT_NULL_FLAG))
1085
1126
          sql_field->decimals=          dup_field->decimals;
1086
1127
          sql_field->create_length_to_internal_length();
1087
1128
          sql_field->unireg_check=      dup_field->unireg_check;
1088
 
          /* 
 
1129
          /*
1089
1130
            We're making one field from two, the result field will have
1090
1131
            dup_field->flags as flags. If we've incremented null_fields
1091
1132
            because of sql_field->flags, decrement it back.
1094
1135
            null_fields--;
1095
1136
          sql_field->flags=             dup_field->flags;
1096
1137
          sql_field->interval=          dup_field->interval;
 
1138
          sql_field->vcol_info=         dup_field->vcol_info;
 
1139
          sql_field->is_stored=      dup_field->is_stored;
1097
1140
          it2.remove();                 // Remove first (create) definition
1098
1141
          select_field_pos--;
1099
1142
          break;
1116
1159
  {
1117
1160
    assert(sql_field->charset != 0);
1118
1161
 
1119
 
    if (prepare_create_field(sql_field, &blob_columns, 
 
1162
    if (prepare_create_field(sql_field, &blob_columns,
1120
1163
                             &timestamps, &timestamps_with_niladic,
1121
1164
                             file->ha_table_flags()))
1122
1165
      return(true);
1125
1168
    sql_field->offset= record_offset;
1126
1169
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1127
1170
      auto_increment++;
1128
 
    record_offset+= sql_field->pack_length;
 
1171
    /*
 
1172
          For now skip fields that are not physically stored in the database
 
1173
          (virtual fields) and update their offset later
 
1174
          (see the next loop).
 
1175
        */
 
1176
    if (sql_field->is_stored)
 
1177
      record_offset+= sql_field->pack_length;
 
1178
  }
 
1179
  /* Update virtual fields' offset */
 
1180
  it.rewind();
 
1181
  while ((sql_field=it++))
 
1182
  {
 
1183
    if (not sql_field->is_stored)
 
1184
    {
 
1185
      sql_field->offset= record_offset;
 
1186
      record_offset+= sql_field->pack_length;
 
1187
    }
1129
1188
  }
1130
1189
  if (timestamps_with_niladic > 1)
1131
1190
  {
1172
1231
    if (key->type == Key::FOREIGN_KEY)
1173
1232
    {
1174
1233
      fk_key_count++;
 
1234
      if (((Foreign_key *)key)->validate(alter_info->create_list))
 
1235
        return true;
1175
1236
      Foreign_key *fk_key= (Foreign_key*) key;
1176
1237
      if (fk_key->ref_columns.elements &&
1177
1238
          fk_key->ref_columns.elements != fk_key->columns.elements)
1228
1289
    else
1229
1290
      (*key_count)--;
1230
1291
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
1231
 
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
 
1292
        is_primary_key_name(key->name.str))
1232
1293
    {
1233
1294
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1234
1295
      return(true);
1361
1422
            return(true);
1362
1423
          }
1363
1424
        }
 
1425
        if (not sql_field->is_stored)
 
1426
        {
 
1427
          /* Key fields must always be physically stored. */
 
1428
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
 
1429
          return(true);
 
1430
        }
 
1431
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
 
1432
        {
 
1433
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
 
1434
          return(true);
 
1435
        }
1364
1436
        if (!(sql_field->flags & NOT_NULL_FLAG))
1365
1437
        {
1366
1438
          if (key->type == Key::PRIMARY)
1406
1478
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
1407
1479
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1408
1480
                       length);
1409
 
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1481
              push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1410
1482
                           ER_TOO_LONG_KEY, warn_buff);
1411
1483
              /* Align key length to multibyte char boundary */
1412
1484
              length-= length % sql_field->charset->mbmaxlen;
1445
1517
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1446
1518
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1447
1519
                   length);
1448
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1520
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1449
1521
                       ER_TOO_LONG_KEY, warn_buff);
1450
1522
          /* Align key length to multibyte char boundary */
1451
1523
          length-= length % sql_field->charset->mbmaxlen;
1487
1559
                       MYF(0));
1488
1560
            return(true);
1489
1561
          }
1490
 
          key_name=primary_key_name;
 
1562
          static const char pkey_name[]= "PRIMARY";
 
1563
          key_name=pkey_name;
1491
1564
          primary_key=1;
1492
1565
        }
1493
1566
        else if (!(key_name= key->name.str))
1538
1611
  {
1539
1612
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1540
1613
 
1541
 
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
 
1614
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1542
1615
        !sql_field->def &&
1543
1616
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1544
1617
        (sql_field->flags & NOT_NULL_FLAG) &&
1580
1653
    apply it to the table.
1581
1654
*/
1582
1655
 
1583
 
static void set_table_default_charset(THD *thd,
1584
 
                                      HA_CREATE_INFO *create_info, char *db)
 
1656
static void set_table_default_charset(Session *session,
 
1657
                                      HA_CREATE_INFO *create_info, char *db)
1585
1658
{
1586
1659
  /*
1587
1660
    If the table character set was not given explicitly,
1592
1665
  {
1593
1666
    HA_CREATE_INFO db_info;
1594
1667
 
1595
 
    load_db_opt_by_name(thd, db, &db_info);
 
1668
    load_db_opt_by_name(session, db, &db_info);
1596
1669
 
1597
1670
    create_info->default_table_charset= db_info.default_table_charset;
1598
1671
  }
1612
1685
        In this case the error is given
1613
1686
*/
1614
1687
 
1615
 
static bool prepare_blob_field(THD *thd __attribute__((unused)),
 
1688
static bool prepare_blob_field(Session *session __attribute__((unused)),
1616
1689
                               Create_field *sql_field)
1617
1690
{
1618
1691
 
1623
1696
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1624
1697
    return(1);
1625
1698
  }
1626
 
    
 
1699
 
1627
1700
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1628
1701
  {
1629
1702
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1639
1712
 
1640
1713
 
1641
1714
/*
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
1715
  Create a table
1680
1716
 
1681
1717
  SYNOPSIS
1682
1718
    mysql_create_table_no_lock()
1683
 
    thd                 Thread object
 
1719
    session                     Thread object
1684
1720
    db                  Database
1685
1721
    table_name          Table name
1686
1722
    create_info         Create information (like MAX_ROWS)
1688
1724
    keys                List of keys to create
1689
1725
    internal_tmp_table  Set to 1 if this is an internal temporary table
1690
1726
                        (From ALTER Table)
1691
 
    select_field_count  
 
1727
    select_field_count
1692
1728
 
1693
1729
  DESCRIPTION
1694
1730
    If one creates a temporary table, this is automatically opened
1708
1744
    true  error
1709
1745
*/
1710
1746
 
1711
 
bool mysql_create_table_no_lock(THD *thd,
 
1747
bool mysql_create_table_no_lock(Session *session,
1712
1748
                                const char *db, const char *table_name,
1713
1749
                                HA_CREATE_INFO *create_info,
1714
1750
                                Alter_info *alter_info,
1715
1751
                                bool internal_tmp_table,
1716
 
                                uint32_t select_field_count)
 
1752
                                uint32_t select_field_count,
 
1753
                                bool lock_open_lock)
1717
1754
{
1718
1755
  char          path[FN_REFLEN];
1719
1756
  uint32_t          path_length;
1729
1766
               MYF(0));
1730
1767
    return(true);
1731
1768
  }
1732
 
  if (check_engine(thd, table_name, create_info))
 
1769
  if (check_engine(session, table_name, create_info))
1733
1770
    return(true);
1734
1771
  db_options= create_info->table_options;
1735
1772
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1736
1773
    db_options|=HA_OPTION_PACK_RECORD;
1737
1774
  alias= table_case_name(create_info, table_name);
1738
 
  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
 
1775
  if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1739
1776
                              create_info->db_type)))
1740
1777
  {
1741
1778
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1742
1779
    return(true);
1743
1780
  }
1744
1781
 
1745
 
  set_table_default_charset(thd, create_info, (char*) db);
 
1782
  set_table_default_charset(session, create_info, (char*) db);
1746
1783
 
1747
 
  if (mysql_prepare_create_table(thd, create_info, alter_info,
 
1784
  if (mysql_prepare_create_table(session, create_info, alter_info,
1748
1785
                                 internal_tmp_table,
1749
1786
                                 &db_options, file,
1750
1787
                          &key_info_buffer, &key_count,
1754
1791
      /* Check if table exists */
1755
1792
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1756
1793
  {
1757
 
    path_length= build_tmptable_filename(thd, path, sizeof(path));
 
1794
    path_length= build_tmptable_filename(session, path, sizeof(path));
1758
1795
    create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1759
1796
  }
1760
 
  else  
 
1797
  else
1761
1798
  {
1762
1799
 #ifdef FN_DEVCHAR
1763
1800
    /* check if the table name contains FN_DEVCHAR when defined */
1773
1810
 
1774
1811
  /* Check if table already exists */
1775
1812
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1776
 
      find_temporary_table(thd, db, table_name))
 
1813
      find_temporary_table(session, db, table_name))
1777
1814
  {
1778
1815
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1779
1816
    {
1780
1817
      create_info->table_existed= 1;            // Mark that table existed
1781
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1818
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1782
1819
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1783
1820
                          alias);
1784
1821
      error= 0;
1788
1825
    goto err;
1789
1826
  }
1790
1827
 
1791
 
  pthread_mutex_lock(&LOCK_open);
 
1828
  if (lock_open_lock)
 
1829
    pthread_mutex_lock(&LOCK_open);
1792
1830
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1793
1831
  {
1794
1832
    if (!access(path,F_OK))
1826
1864
  {
1827
1865
    bool create_if_not_exists =
1828
1866
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1829
 
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
 
1867
    int retcode = ha_table_exists_in_engine(session, db, table_name);
1830
1868
    switch (retcode)
1831
1869
    {
1832
1870
      case HA_ERR_NO_SUCH_TABLE:
1845
1883
    }
1846
1884
  }
1847
1885
 
1848
 
  thd_proc_info(thd, "creating table");
 
1886
  session->set_proc_info("creating table");
1849
1887
  create_info->table_existed= 0;                // Mark that table is created
1850
1888
 
1851
1889
#ifdef HAVE_READLINK
1864
1902
#endif /* HAVE_READLINK */
1865
1903
  {
1866
1904
    if (create_info->data_file_name)
1867
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1905
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1868
1906
                   "DATA DIRECTORY option ignored");
1869
1907
    if (create_info->index_file_name)
1870
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1908
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1871
1909
                   "INDEX DIRECTORY option ignored");
1872
1910
    create_info->data_file_name= create_info->index_file_name= 0;
1873
1911
  }
1874
1912
  create_info->table_options=db_options;
1875
1913
 
1876
1914
  path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1877
 
  if (rea_create_table(thd, path, db, table_name,
 
1915
  if (rea_create_table(session, path, db, table_name,
1878
1916
                       create_info, alter_info->create_list,
1879
1917
                       key_count, key_info_buffer, file))
1880
1918
    goto unlock_and_end;
1882
1920
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1883
1921
  {
1884
1922
    /* Open table and put in temporary table list */
1885
 
    if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
 
1923
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1886
1924
    {
1887
 
      (void) rm_temporary_table(create_info->db_type, path, false);
 
1925
      (void) rm_temporary_table(create_info->db_type, path);
1888
1926
      goto unlock_and_end;
1889
1927
    }
1890
 
    thd->thread_specific_used= true;
 
1928
    session->thread_specific_used= true;
1891
1929
  }
1892
1930
 
1893
1931
  /*
1898
1936
    Otherwise, the statement shall be binlogged.
1899
1937
   */
1900
1938
  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);
 
1939
      ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
 
1940
    write_bin_log(session, true, session->query, session->query_length);
1905
1941
  error= false;
1906
1942
unlock_and_end:
1907
 
  pthread_mutex_unlock(&LOCK_open);
 
1943
  if (lock_open_lock)
 
1944
    pthread_mutex_unlock(&LOCK_open);
1908
1945
 
1909
1946
err:
1910
 
  thd_proc_info(thd, "After create");
 
1947
  session->set_proc_info("After create");
1911
1948
  delete file;
1912
1949
  return(error);
1913
1950
 
1914
1951
warn:
1915
1952
  error= false;
1916
 
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1953
  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1917
1954
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1918
1955
                      alias);
1919
1956
  create_info->table_existed= 1;                // Mark that table existed
1925
1962
  Database locking aware wrapper for mysql_create_table_no_lock(),
1926
1963
*/
1927
1964
 
1928
 
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
 
1965
bool mysql_create_table(Session *session, const char *db, const char *table_name,
1929
1966
                        HA_CREATE_INFO *create_info,
1930
1967
                        Alter_info *alter_info,
1931
1968
                        bool internal_tmp_table,
1936
1973
 
1937
1974
  /* Wait for any database locks */
1938
1975
  pthread_mutex_lock(&LOCK_lock_db);
1939
 
  while (!thd->killed &&
 
1976
  while (!session->killed &&
1940
1977
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
1941
1978
  {
1942
 
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1979
    wait_for_condition(session, &LOCK_lock_db, &COND_refresh);
1943
1980
    pthread_mutex_lock(&LOCK_lock_db);
1944
1981
  }
1945
1982
 
1946
 
  if (thd->killed)
 
1983
  if (session->killed)
1947
1984
  {
1948
1985
    pthread_mutex_unlock(&LOCK_lock_db);
1949
1986
    return(true);
1953
1990
 
1954
1991
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1955
1992
  {
1956
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
1993
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
1957
1994
    {
1958
1995
      result= true;
1959
1996
      goto unlock;
1962
1999
    {
1963
2000
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1964
2001
      {
1965
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2002
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1966
2003
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1967
2004
                            table_name);
1968
2005
        create_info->table_existed= 1;
1977
2014
    }
1978
2015
  }
1979
2016
 
1980
 
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
 
2017
  result= mysql_create_table_no_lock(session, db, table_name, create_info,
1981
2018
                                     alter_info,
1982
2019
                                     internal_tmp_table,
1983
 
                                     select_field_count);
 
2020
                                     select_field_count, true);
1984
2021
 
1985
2022
unlock:
1986
2023
  if (name_lock)
1987
2024
  {
1988
2025
    pthread_mutex_lock(&LOCK_open);
1989
 
    unlink_open_table(thd, name_lock, false);
 
2026
    unlink_open_table(session, name_lock, false);
1990
2027
    pthread_mutex_unlock(&LOCK_open);
1991
2028
  }
1992
2029
  pthread_mutex_lock(&LOCK_lock_db);
2017
2054
  char buff[MAX_FIELD_NAME],*buff_end;
2018
2055
 
2019
2056
  if (!check_if_keyname_exists(field_name,start,end) &&
2020
 
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
 
2057
      !is_primary_key_name(field_name))
2021
2058
    return (char*) field_name;                  // Use fieldname
2022
 
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
 
2059
 
 
2060
  buff_end= strncpy(buff, field_name, sizeof(buff)-4);
 
2061
  buff_end+= strlen(buff);
2023
2062
 
2024
2063
  /*
2025
2064
    Only 3 chars + '\0' left, so need to limit to 2 digit
2067
2106
                   const char *old_name, const char *new_db,
2068
2107
                   const char *new_name, uint32_t flags)
2069
2108
{
2070
 
  THD *thd= current_thd;
 
2109
  Session *session= current_session;
2071
2110
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2072
2111
  char *from_base= from, *to_base= to;
2073
2112
  char tmp_name[NAME_LEN+1];
2075
2114
  int error=0;
2076
2115
 
2077
2116
  file= (base == NULL ? 0 :
2078
 
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
 
2117
         get_new_handler((TABLE_SHARE*) 0, session->mem_root, base));
2079
2118
 
2080
2119
  build_table_filename(from, sizeof(from), old_db, old_name, "",
2081
2120
                       flags & FN_FROM_IS_TMP);
2090
2129
  if (lower_case_table_names == 2 && file &&
2091
2130
      !(file->ha_table_flags() & HA_FILE_BASED))
2092
2131
  {
2093
 
    my_stpcpy(tmp_name, old_name);
 
2132
    strcpy(tmp_name, old_name);
2094
2133
    my_casedn_str(files_charset_info, tmp_name);
2095
2134
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2096
2135
                         flags & FN_FROM_IS_TMP);
2097
2136
    from_base= lc_from;
2098
2137
 
2099
 
    my_stpcpy(tmp_name, new_name);
 
2138
    strcpy(tmp_name, new_name);
2100
2139
    my_casedn_str(files_charset_info, tmp_name);
2101
2140
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2102
2141
                         flags & FN_TO_IS_TMP);
2111
2150
      if (file)
2112
2151
        file->ha_rename_table(to_base, from_base);
2113
2152
    }
 
2153
 
 
2154
    if(!(flags & NO_FRM_RENAME)
 
2155
       && rename_table_proto_file(from_base, to_base))
 
2156
    {
 
2157
      error= errno;
 
2158
      rename_file_ext(to, from, reg_ext);
 
2159
      if (file)
 
2160
        file->ha_rename_table(to_base, from_base);
 
2161
    }
2114
2162
  }
2115
2163
  delete file;
2116
2164
  if (error == HA_ERR_WRONG_COMMAND)
2126
2174
 
2127
2175
  SYNOPSIS
2128
2176
    wait_while_table_is_used()
2129
 
    thd                 Thread handler
 
2177
    session                     Thread handler
2130
2178
    table               Table to remove from cache
2131
2179
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2132
2180
                        HA_EXTRA_FORCE_REOPEN if table is not be used
2140
2188
    Win32 clients must also have a WRITE LOCK on the table !
2141
2189
*/
2142
2190
 
2143
 
void wait_while_table_is_used(THD *thd, Table *table,
 
2191
void wait_while_table_is_used(Session *session, Table *table,
2144
2192
                              enum ha_extra_function function)
2145
2193
{
2146
2194
 
2148
2196
 
2149
2197
  table->file->extra(function);
2150
2198
  /* Mark all tables that are in use as 'old' */
2151
 
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
 
2199
  mysql_lock_abort(session, table, true);       /* end threads waiting on lock */
2152
2200
 
2153
2201
  /* Wait until all there are no other threads that has this table open */
2154
 
  remove_table_from_cache(thd, table->s->db.str,
 
2202
  remove_table_from_cache(session, table->s->db.str,
2155
2203
                          table->s->table_name.str,
2156
2204
                          RTFC_WAIT_OTHER_THREAD_FLAG);
2157
2205
  return;
2162
2210
 
2163
2211
  SYNOPSIS
2164
2212
    close_cached_table()
2165
 
    thd                 Thread handler
 
2213
    session                     Thread handler
2166
2214
    table               Table to remove from cache
2167
2215
 
2168
2216
  NOTES
2174
2222
    Win32 clients must also have a WRITE LOCK on the table !
2175
2223
*/
2176
2224
 
2177
 
void close_cached_table(THD *thd, Table *table)
 
2225
void close_cached_table(Session *session, Table *table)
2178
2226
{
2179
2227
 
2180
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
2228
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2181
2229
  /* Close lock if this is not got with LOCK TABLES */
2182
 
  if (thd->lock)
 
2230
  if (session->lock)
2183
2231
  {
2184
 
    mysql_unlock_tables(thd, thd->lock);
2185
 
    thd->lock=0;                        // Start locked threads
 
2232
    mysql_unlock_tables(session, session->lock);
 
2233
    session->lock=0;                    // Start locked threads
2186
2234
  }
2187
2235
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
2188
 
  unlink_open_table(thd, table, true);
 
2236
  unlink_open_table(session, table, true);
2189
2237
 
2190
2238
  /* When lock on LOCK_open is freed other threads can continue */
2191
2239
  broadcast_refresh();
2192
2240
  return;
2193
2241
}
2194
2242
 
2195
 
static int send_check_errmsg(THD *thd, TableList* table,
 
2243
static int send_check_errmsg(Session *session, TableList* table,
2196
2244
                             const char* operator_name, const char* errmsg)
2197
2245
 
2198
2246
{
2199
 
  Protocol *protocol= thd->protocol;
 
2247
  Protocol *protocol= session->protocol;
2200
2248
  protocol->prepare_for_resend();
2201
2249
  protocol->store(table->alias, system_charset_info);
2202
2250
  protocol->store((char*) operator_name, system_charset_info);
2203
2251
  protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2204
2252
  protocol->store(errmsg, system_charset_info);
2205
 
  thd->clear_error();
 
2253
  session->clear_error();
2206
2254
  if (protocol->write())
2207
2255
    return -1;
2208
2256
  return 1;
2209
2257
}
2210
2258
 
2211
2259
 
2212
 
static int prepare_for_repair(THD *thd, TableList *table_list,
 
2260
static int prepare_for_repair(Session *session, TableList *table_list,
2213
2261
                              HA_CHECK_OPT *check_opt)
2214
2262
{
2215
2263
  int error= 0;
2227
2275
    char key[MAX_DBKEY_LENGTH];
2228
2276
    uint32_t key_length;
2229
2277
 
2230
 
    key_length= create_table_def_key(thd, key, table_list, 0);
 
2278
    key_length= create_table_def_key(session, key, table_list, 0);
2231
2279
    pthread_mutex_lock(&LOCK_open);
2232
 
    if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
 
2280
    if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2233
2281
                                  &error))))
2234
2282
    {
2235
2283
      pthread_mutex_unlock(&LOCK_open);
2236
2284
      return(0);                                // Can't open frm file
2237
2285
    }
2238
2286
 
2239
 
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
 
2287
    if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2240
2288
    {
2241
2289
      release_table_share(share, RELEASE_NORMAL);
2242
2290
      pthread_mutex_unlock(&LOCK_open);
2251
2299
  */
2252
2300
  if (table->s->tmp_table)
2253
2301
  {
2254
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2302
    error= send_check_errmsg(session, table_list, "repair",
2255
2303
                             "Cannot repair temporary table from .frm file");
2256
2304
    goto end;
2257
2305
  }
2270
2318
    Check if this is a table type that stores index and data separately,
2271
2319
    like ISAM or MyISAM. We assume fixed order of engine file name
2272
2320
    extentions array. First element of engine file name extentions array
2273
 
    is meta/index file extention. Second element - data file extention. 
 
2321
    is meta/index file extention. Second element - data file extention.
2274
2322
  */
2275
2323
  ext= table->file->bas_ext();
2276
2324
  if (!ext[0] || !ext[1])
2277
2325
    goto end;                                   // No data file
2278
2326
 
2279
2327
  // Name of data file
2280
 
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
 
2328
  sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2281
2329
  if (stat(from, &stat_info))
2282
2330
    goto end;                           // Can't use USE_FRM flag
2283
2331
 
2284
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2285
 
           from, current_pid, thd->thread_id);
 
2332
  snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
 
2333
           from, (unsigned long)current_pid, session->thread_id);
2286
2334
 
2287
2335
  /* If we could open the table, close it */
2288
2336
  if (table_list->table)
2289
2337
  {
2290
2338
    pthread_mutex_lock(&LOCK_open);
2291
 
    close_cached_table(thd, table);
 
2339
    close_cached_table(session, table);
2292
2340
    pthread_mutex_unlock(&LOCK_open);
2293
2341
  }
2294
 
  if (lock_and_wait_for_table_name(thd,table_list))
 
2342
  if (lock_and_wait_for_table_name(session,table_list))
2295
2343
  {
2296
2344
    error= -1;
2297
2345
    goto end;
2299
2347
  if (my_rename(from, tmp, MYF(MY_WME)))
2300
2348
  {
2301
2349
    pthread_mutex_lock(&LOCK_open);
2302
 
    unlock_table_name(thd, table_list);
 
2350
    unlock_table_name(session, table_list);
2303
2351
    pthread_mutex_unlock(&LOCK_open);
2304
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2352
    error= send_check_errmsg(session, table_list, "repair",
2305
2353
                             "Failed renaming data file");
2306
2354
    goto end;
2307
2355
  }
2308
 
  if (mysql_truncate(thd, table_list, 1))
 
2356
  if (mysql_truncate(session, table_list, 1))
2309
2357
  {
2310
2358
    pthread_mutex_lock(&LOCK_open);
2311
 
    unlock_table_name(thd, table_list);
 
2359
    unlock_table_name(session, table_list);
2312
2360
    pthread_mutex_unlock(&LOCK_open);
2313
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2361
    error= send_check_errmsg(session, table_list, "repair",
2314
2362
                             "Failed generating table from .frm file");
2315
2363
    goto end;
2316
2364
  }
2317
2365
  if (my_rename(tmp, from, MYF(MY_WME)))
2318
2366
  {
2319
2367
    pthread_mutex_lock(&LOCK_open);
2320
 
    unlock_table_name(thd, table_list);
 
2368
    unlock_table_name(session, table_list);
2321
2369
    pthread_mutex_unlock(&LOCK_open);
2322
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2370
    error= send_check_errmsg(session, table_list, "repair",
2323
2371
                             "Failed restoring .MYD file");
2324
2372
    goto end;
2325
2373
  }
2329
2377
    to finish the repair in the handler later on.
2330
2378
  */
2331
2379
  pthread_mutex_lock(&LOCK_open);
2332
 
  if (reopen_name_locked_table(thd, table_list, true))
 
2380
  if (reopen_name_locked_table(session, table_list, true))
2333
2381
  {
2334
 
    unlock_table_name(thd, table_list);
 
2382
    unlock_table_name(session, table_list);
2335
2383
    pthread_mutex_unlock(&LOCK_open);
2336
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2384
    error= send_check_errmsg(session, table_list, "repair",
2337
2385
                             "Failed to open partially repaired table");
2338
2386
    goto end;
2339
2387
  }
2354
2402
/*
2355
2403
  RETURN VALUES
2356
2404
    false Message sent to net (admin operation went ok)
2357
 
    true  Message should be sent by caller 
 
2405
    true  Message should be sent by caller
2358
2406
          (admin operation or network communication failed)
2359
2407
*/
2360
 
static bool mysql_admin_table(THD* thd, TableList* tables,
 
2408
static bool mysql_admin_table(Session* session, TableList* tables,
2361
2409
                              HA_CHECK_OPT* check_opt,
2362
2410
                              const char *operator_name,
2363
2411
                              thr_lock_type lock_type,
2364
2412
                              bool open_for_modify,
2365
2413
                              bool no_warnings_for_error,
2366
2414
                              uint32_t extra_open_options,
2367
 
                              int (*prepare_func)(THD *, TableList *,
 
2415
                              int (*prepare_func)(Session *, TableList *,
2368
2416
                                                  HA_CHECK_OPT *),
2369
 
                              int (handler::*operator_func)(THD *,
 
2417
                              int (handler::*operator_func)(Session *,
2370
2418
                                                            HA_CHECK_OPT *))
2371
2419
{
2372
2420
  TableList *table;
2373
 
  SELECT_LEX *select= &thd->lex->select_lex;
 
2421
  SELECT_LEX *select= &session->lex->select_lex;
2374
2422
  List<Item> field_list;
2375
2423
  Item *item;
2376
 
  Protocol *protocol= thd->protocol;
2377
 
  LEX *lex= thd->lex;
 
2424
  Protocol *protocol= session->protocol;
 
2425
  LEX *lex= session->lex;
2378
2426
  int result_code= 0;
2379
2427
  const CHARSET_INFO * const cs= system_charset_info;
2380
2428
 
2381
 
  if (end_active_trans(thd))
 
2429
  if (end_active_trans(session))
2382
2430
    return(1);
2383
2431
  field_list.push_back(item = new Item_empty_string("Table",
2384
2432
                                                    NAME_CHAR_LEN * 2,
2394
2442
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2395
2443
    return(true);
2396
2444
 
2397
 
  mysql_ha_rm_tables(thd, tables, false);
 
2445
  mysql_ha_rm_tables(session, tables, false);
2398
2446
 
2399
2447
  for (table= tables; table; table= table->next_local)
2400
2448
  {
2402
2450
    char* db = table->db;
2403
2451
    bool fatal_error=0;
2404
2452
 
2405
 
    strxmov(table_name, db, ".", table->table_name, NULL);
2406
 
    thd->open_options|= extra_open_options;
 
2453
    sprintf(table_name,"%s.%s",db,table->table_name);
 
2454
    session->open_options|= extra_open_options;
2407
2455
    table->lock_type= lock_type;
2408
2456
    /* open only one table from local list of command */
2409
2457
    {
2422
2470
      lex->query_tables= table;
2423
2471
      lex->query_tables_last= &table->next_global;
2424
2472
      lex->query_tables_own_last= 0;
2425
 
      thd->no_warnings_for_error= no_warnings_for_error;
 
2473
      session->no_warnings_for_error= no_warnings_for_error;
2426
2474
 
2427
 
      open_and_lock_tables(thd, table);
2428
 
      thd->no_warnings_for_error= 0;
 
2475
      open_and_lock_tables(session, table);
 
2476
      session->no_warnings_for_error= 0;
2429
2477
      table->next_global= save_next_global;
2430
2478
      table->next_local= save_next_local;
2431
 
      thd->open_options&= ~extra_open_options;
 
2479
      session->open_options&= ~extra_open_options;
2432
2480
    }
2433
2481
 
2434
2482
    if (prepare_func)
2435
2483
    {
2436
 
      switch ((*prepare_func)(thd, table, check_opt)) {
 
2484
      switch ((*prepare_func)(session, table, check_opt)) {
2437
2485
      case  1:           // error, message written to net
2438
 
        ha_autocommit_or_rollback(thd, 1);
2439
 
        end_trans(thd, ROLLBACK);
2440
 
        close_thread_tables(thd);
 
2486
        ha_autocommit_or_rollback(session, 1);
 
2487
        end_trans(session, ROLLBACK);
 
2488
        close_thread_tables(session);
2441
2489
        continue;
2442
2490
      case -1:           // error, message could be written to net
2443
2491
        /* purecov: begin inspected */
2458
2506
    */
2459
2507
    if (!table->table)
2460
2508
    {
2461
 
      if (!thd->warn_list.elements)
2462
 
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2509
      if (!session->warn_list.elements)
 
2510
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
2463
2511
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2464
2512
      goto send_result;
2465
2513
    }
2476
2524
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2477
2525
                       table_name);
2478
2526
      protocol->store(buff, length, system_charset_info);
2479
 
      ha_autocommit_or_rollback(thd, 0);
2480
 
      end_trans(thd, COMMIT);
2481
 
      close_thread_tables(thd);
 
2527
      ha_autocommit_or_rollback(session, 0);
 
2528
      end_trans(session, COMMIT);
 
2529
      close_thread_tables(session);
2482
2530
      lex->reset_query_tables_list(false);
2483
2531
      table->table=0;                           // For query cache
2484
2532
      if (protocol->write())
2491
2539
    if (lock_type == TL_WRITE && table->table->s->version)
2492
2540
    {
2493
2541
      pthread_mutex_lock(&LOCK_open);
2494
 
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
 
2542
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2495
2543
                                              "Waiting to get writelock");
2496
 
      mysql_lock_abort(thd,table->table, true);
2497
 
      remove_table_from_cache(thd, table->table->s->db.str,
 
2544
      mysql_lock_abort(session,table->table, true);
 
2545
      remove_table_from_cache(session, table->table->s->db.str,
2498
2546
                              table->table->s->table_name.str,
2499
2547
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2500
2548
                              RTFC_CHECK_KILLED_FLAG);
2501
 
      thd->exit_cond(old_message);
2502
 
      if (thd->killed)
 
2549
      session->exit_cond(old_message);
 
2550
      if (session->killed)
2503
2551
        goto err;
2504
2552
      open_for_modify= 0;
2505
2553
    }
2525
2573
          (table->table->file->ha_check_for_upgrade(check_opt) ==
2526
2574
           HA_ADMIN_NEEDS_ALTER))
2527
2575
      {
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);
 
2576
        ha_autocommit_or_rollback(session, 1);
 
2577
        close_thread_tables(session);
 
2578
        tmp_disable_binlog(session); // binlogging is done by caller if wanted
 
2579
        result_code= mysql_recreate_table(session, table);
 
2580
        reenable_binlog(session);
2533
2581
        /*
2534
2582
          mysql_recreate_table() can push OK or ERROR.
2535
2583
          Clear 'OK' status. If there is an error, keep it:
2536
 
          we will store the error message in a result set row 
 
2584
          we will store the error message in a result set row
2537
2585
          and then clear.
2538
2586
        */
2539
 
        if (thd->main_da.is_ok())
2540
 
          thd->main_da.reset_diagnostics_area();
 
2587
        if (session->main_da.is_ok())
 
2588
          session->main_da.reset_diagnostics_area();
2541
2589
        goto send_result;
2542
2590
      }
2543
2591
    }
2544
2592
 
2545
 
    result_code = (table->table->file->*operator_func)(thd, check_opt);
 
2593
    result_code = (table->table->file->*operator_func)(session, check_opt);
2546
2594
 
2547
2595
send_result:
2548
2596
 
2549
2597
    lex->cleanup_after_one_table_open();
2550
 
    thd->clear_error();  // these errors shouldn't get client
 
2598
    session->clear_error();  // these errors shouldn't get client
2551
2599
    {
2552
 
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
2600
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2553
2601
      DRIZZLE_ERROR *err;
2554
2602
      while ((err= it++))
2555
2603
      {
2563
2611
        if (protocol->write())
2564
2612
          goto err;
2565
2613
      }
2566
 
      drizzle_reset_errors(thd, true);
 
2614
      drizzle_reset_errors(session, true);
2567
2615
    }
2568
2616
    protocol->prepare_for_resend();
2569
2617
    protocol->store(table_name, system_charset_info);
2635
2683
        "try with alter", so here we close the table, do an ALTER Table,
2636
2684
        reopen the table and do ha_innobase::analyze() on it.
2637
2685
      */
2638
 
      ha_autocommit_or_rollback(thd, 0);
2639
 
      close_thread_tables(thd);
 
2686
      ha_autocommit_or_rollback(session, 0);
 
2687
      close_thread_tables(session);
2640
2688
      TableList *save_next_local= table->next_local,
2641
2689
                 *save_next_global= table->next_global;
2642
2690
      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);
 
2691
      tmp_disable_binlog(session); // binlogging is done by caller if wanted
 
2692
      result_code= mysql_recreate_table(session, table);
 
2693
      reenable_binlog(session);
2646
2694
      /*
2647
2695
        mysql_recreate_table() can push OK or ERROR.
2648
2696
        Clear 'OK' status. If there is an error, keep it:
2649
 
        we will store the error message in a result set row 
 
2697
        we will store the error message in a result set row
2650
2698
        and then clear.
2651
2699
      */
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);
 
2700
      if (session->main_da.is_ok())
 
2701
        session->main_da.reset_diagnostics_area();
 
2702
      ha_autocommit_or_rollback(session, 0);
 
2703
      close_thread_tables(session);
2656
2704
      if (!result_code) // recreation went ok
2657
2705
      {
2658
 
        if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
2659
 
            ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
 
2706
        if ((table->table= open_ltable(session, table, lock_type, 0)) &&
 
2707
            ((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2660
2708
          result_code= 0; // analyze went ok
2661
2709
      }
2662
2710
      if (result_code) // either mysql_recreate_table or analyze failed
2663
2711
      {
2664
 
        assert(thd->is_error());
2665
 
        if (thd->is_error())
 
2712
        assert(session->is_error());
 
2713
        if (session->is_error())
2666
2714
        {
2667
 
          const char *err_msg= thd->main_da.message();
2668
 
          if (!thd->vio_ok())
 
2715
          const char *err_msg= session->main_da.message();
 
2716
          if (!session->vio_ok())
2669
2717
          {
2670
 
            sql_print_error(err_msg);
 
2718
            sql_print_error("%s",err_msg);
2671
2719
          }
2672
2720
          else
2673
2721
          {
2680
2728
            protocol->store(table_name, system_charset_info);
2681
2729
            protocol->store(operator_name, system_charset_info);
2682
2730
          }
2683
 
          thd->clear_error();
 
2731
          session->clear_error();
2684
2732
        }
2685
2733
      }
2686
2734
      result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
2732
2780
        else
2733
2781
        {
2734
2782
          pthread_mutex_lock(&LOCK_open);
2735
 
          remove_table_from_cache(thd, table->table->s->db.str,
 
2783
          remove_table_from_cache(session, table->table->s->db.str,
2736
2784
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
2737
2785
          pthread_mutex_unlock(&LOCK_open);
2738
2786
        }
2739
2787
      }
2740
2788
    }
2741
 
    ha_autocommit_or_rollback(thd, 0);
2742
 
    end_trans(thd, COMMIT);
2743
 
    close_thread_tables(thd);
 
2789
    ha_autocommit_or_rollback(session, 0);
 
2790
    end_trans(session, COMMIT);
 
2791
    close_thread_tables(session);
2744
2792
    table->table=0;                             // For query cache
2745
2793
    if (protocol->write())
2746
2794
      goto err;
2747
2795
  }
2748
2796
 
2749
 
  my_eof(thd);
 
2797
  my_eof(session);
2750
2798
  return(false);
2751
2799
 
2752
2800
err:
2753
 
  ha_autocommit_or_rollback(thd, 1);
2754
 
  end_trans(thd, ROLLBACK);
2755
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
2801
  ha_autocommit_or_rollback(session, 1);
 
2802
  end_trans(session, ROLLBACK);
 
2803
  close_thread_tables(session);                 // Shouldn't be needed
2756
2804
  if (table)
2757
2805
    table->table=0;
2758
2806
  return(true);
2759
2807
}
2760
2808
 
2761
2809
 
2762
 
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2810
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2763
2811
{
2764
 
  return(mysql_admin_table(thd, tables, check_opt,
 
2812
  return(mysql_admin_table(session, tables, check_opt,
2765
2813
                                "repair", TL_WRITE, 1,
2766
2814
                                test(check_opt->sql_flags & TT_USEFRM),
2767
2815
                                HA_OPEN_FOR_REPAIR,
2770
2818
}
2771
2819
 
2772
2820
 
2773
 
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2821
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2774
2822
{
2775
 
  return(mysql_admin_table(thd, tables, check_opt,
 
2823
  return(mysql_admin_table(session, tables, check_opt,
2776
2824
                                "optimize", TL_WRITE, 1,0,0,0,
2777
2825
                                &handler::ha_optimize));
2778
2826
}
2783
2831
 
2784
2832
  SYNOPSIS
2785
2833
    mysql_assign_to_keycache()
2786
 
    thd         Thread object
 
2834
    session             Thread object
2787
2835
    tables      Table list (one table only)
2788
2836
 
2789
2837
  RETURN VALUES
2791
2839
   true  error
2792
2840
*/
2793
2841
 
2794
 
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
 
2842
bool mysql_assign_to_keycache(Session* session, TableList* tables,
2795
2843
                             LEX_STRING *key_cache_name)
2796
2844
{
2797
2845
  HA_CHECK_OPT check_opt;
2807
2855
  }
2808
2856
  pthread_mutex_unlock(&LOCK_global_system_variables);
2809
2857
  check_opt.key_cache= key_cache;
2810
 
  return(mysql_admin_table(thd, tables, &check_opt,
 
2858
  return(mysql_admin_table(session, tables, &check_opt,
2811
2859
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
2812
2860
                                0, 0, &handler::assign_to_keycache));
2813
2861
}
2818
2866
 
2819
2867
  SYNOPSIS
2820
2868
    reassign_keycache_tables()
2821
 
    thd         Thread object
 
2869
    session             Thread object
2822
2870
    src_cache   Reference to the key cache to clean up
2823
2871
    dest_cache  New key cache
2824
2872
 
2838
2886
    0     ok
2839
2887
*/
2840
2888
 
2841
 
int reassign_keycache_tables(THD *thd __attribute__((unused)),
 
2889
int reassign_keycache_tables(Session *session __attribute__((unused)),
2842
2890
                             KEY_CACHE *src_cache,
2843
2891
                             KEY_CACHE *dst_cache)
2844
2892
{
2853
2901
/**
2854
2902
  @brief          Create frm file based on I_S table
2855
2903
 
2856
 
  @param[in]      thd                      thread handler
2857
 
  @param[in]      schema_table             I_S table           
 
2904
  @param[in]      session                      thread handler
 
2905
  @param[in]      schema_table             I_S table
2858
2906
  @param[in]      dst_path                 path where frm should be created
2859
2907
  @param[in]      create_info              Create info
2860
2908
 
2862
2910
    @retval       0                        success
2863
2911
    @retval       1                        error
2864
2912
*/
2865
 
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
 
2913
bool mysql_create_like_schema_frm(Session* session, TableList* schema_table,
2866
2914
                                  char *dst_path, HA_CREATE_INFO *create_info)
2867
2915
{
2868
2916
  HA_CREATE_INFO local_create_info;
2877
2925
  local_create_info.default_table_charset=default_charset_info;
2878
2926
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2879
2927
  schema_table->table->use_all_columns();
2880
 
  if (mysql_prepare_alter_table(thd, schema_table->table,
 
2928
  if (mysql_prepare_alter_table(session, schema_table->table,
2881
2929
                                &local_create_info, &alter_info))
2882
2930
    return(1);
2883
 
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
 
2931
  if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2884
2932
                                 tmp_table, &db_options,
2885
2933
                                 schema_table->table->file,
2886
2934
                                 &schema_table->table->s->key_info, &keys, 0))
2887
2935
    return(1);
2888
2936
  local_create_info.max_rows= 0;
2889
 
  if (mysql_create_frm(thd, dst_path, NULL, NULL,
 
2937
  if (mysql_create_frm(session, dst_path, NULL, NULL,
2890
2938
                       &local_create_info, alter_info.create_list,
2891
2939
                       keys, schema_table->table->s->key_info,
2892
2940
                       schema_table->table->file))
2900
2948
 
2901
2949
  SYNOPSIS
2902
2950
    mysql_create_like_table()
2903
 
    thd         Thread object
 
2951
    session             Thread object
2904
2952
    table       Table list element for target table
2905
2953
    src_table   Table list element for source table
2906
2954
    create_info Create info
2910
2958
    true  error
2911
2959
*/
2912
2960
 
2913
 
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
 
2961
bool mysql_create_like_table(Session* session, TableList* table, TableList* src_table,
2914
2962
                             HA_CREATE_INFO *create_info)
2915
2963
{
2916
2964
  Table *name_lock= 0;
2931
2979
    we ensure that our statement is properly isolated from all concurrent
2932
2980
    operations which matter.
2933
2981
  */
2934
 
  if (open_tables(thd, &src_table, &not_used, 0))
 
2982
  if (open_tables(session, &src_table, &not_used, 0))
2935
2983
    return(true);
2936
2984
 
2937
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
 
2985
  sprintf(src_path,"%s%s",src_table->table->s->path.str, reg_ext);
2938
2986
 
2939
 
  /* 
 
2987
  /*
2940
2988
    Check that destination tables does not exist. Note that its name
2941
2989
    was already checked when it was added to the table list.
2942
2990
  */
2943
2991
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2944
2992
  {
2945
 
    if (find_temporary_table(thd, db, table_name))
 
2993
    if (find_temporary_table(session, db, table_name))
2946
2994
      goto table_exists;
2947
 
    dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
 
2995
    dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2948
2996
    create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2949
2997
  }
2950
2998
  else
2951
2999
  {
2952
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
3000
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2953
3001
      goto err;
2954
3002
    if (!name_lock)
2955
3003
      goto table_exists;
2975
3023
  pthread_mutex_lock(&LOCK_open);
2976
3024
  if (src_table->schema_table)
2977
3025
  {
2978
 
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
 
3026
    if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
2979
3027
    {
2980
3028
      pthread_mutex_unlock(&LOCK_open);
2981
3029
      goto err;
2997
3045
    and temporary tables).
2998
3046
  */
2999
3047
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
3000
 
  if (thd->variables.keep_files_on_create)
 
3048
  if (session->variables.keep_files_on_create)
3001
3049
    create_info->options|= HA_CREATE_KEEP_FILES;
3002
 
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
 
3050
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
3003
3051
  pthread_mutex_unlock(&LOCK_open);
3004
3052
 
3005
3053
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3006
3054
  {
3007
 
    if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
 
3055
    if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3008
3056
                                     OTM_OPEN))
3009
3057
    {
3010
3058
      (void) rm_temporary_table(create_info->db_type,
3011
 
                                dst_path, false); /* purecov: inspected */
 
3059
                                dst_path);
3012
3060
      goto err;     /* purecov: inspected */
3013
3061
    }
3014
3062
  }
3022
3070
  /*
3023
3071
    We have to write the query before we unlock the tables.
3024
3072
  */
3025
 
  if (thd->current_stmt_binlog_row_based)
3026
3073
  {
3027
3074
    /*
3028
3075
       Since temporary tables are not replicated under row-based
3056
3103
        */
3057
3104
        table->table= name_lock;
3058
3105
        pthread_mutex_lock(&LOCK_open);
3059
 
        if (reopen_name_locked_table(thd, table, false))
 
3106
        if (reopen_name_locked_table(session, table, false))
3060
3107
        {
3061
3108
          pthread_mutex_unlock(&LOCK_open);
3062
3109
          goto err;
3063
3110
        }
3064
3111
        pthread_mutex_unlock(&LOCK_open);
3065
3112
 
3066
 
        int result= store_create_info(thd, table, &query,
 
3113
        int result= store_create_info(session, table, &query,
3067
3114
                                               create_info);
3068
3115
 
3069
3116
        assert(result == 0); // store_create_info() always return 0
3070
 
        write_bin_log(thd, true, query.ptr(), query.length());
 
3117
        write_bin_log(session, true, query.ptr(), query.length());
3071
3118
      }
3072
3119
      else                                      // Case 1
3073
 
        write_bin_log(thd, true, thd->query, thd->query_length);
 
3120
        write_bin_log(session, true, session->query, session->query_length);
3074
3121
    }
3075
3122
    /*
3076
3123
      Case 3 and 4 does nothing under RBR
3077
3124
    */
3078
3125
  }
3079
 
  else
3080
 
    write_bin_log(thd, true, thd->query, thd->query_length);
3081
3126
 
3082
3127
  res= false;
3083
3128
  goto err;
3088
3133
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
3089
3134
    snprintf(warn_buff, sizeof(warn_buff),
3090
3135
             ER(ER_TABLE_EXISTS_ERROR), table_name);
3091
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3136
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3092
3137
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3093
3138
    res= false;
3094
3139
  }
3099
3144
  if (name_lock)
3100
3145
  {
3101
3146
    pthread_mutex_lock(&LOCK_open);
3102
 
    unlink_open_table(thd, name_lock, false);
 
3147
    unlink_open_table(session, name_lock, false);
3103
3148
    pthread_mutex_unlock(&LOCK_open);
3104
3149
  }
3105
3150
  return(res);
3106
3151
}
3107
3152
 
3108
3153
 
3109
 
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3154
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3110
3155
{
3111
3156
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3112
3157
 
3113
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3158
  return(mysql_admin_table(session, tables, check_opt,
3114
3159
                                "analyze", lock_type, 1, 0, 0, 0,
3115
3160
                                &handler::ha_analyze));
3116
3161
}
3117
3162
 
3118
3163
 
3119
 
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
 
3164
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3120
3165
{
3121
3166
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3122
3167
 
3123
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3168
  return(mysql_admin_table(session, tables, check_opt,
3124
3169
                                "check", lock_type,
3125
3170
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
3126
3171
                                &handler::ha_check));
3129
3174
 
3130
3175
/* table_list should contain just one table */
3131
3176
static int
3132
 
mysql_discard_or_import_tablespace(THD *thd,
 
3177
mysql_discard_or_import_tablespace(Session *session,
3133
3178
                                   TableList *table_list,
3134
3179
                                   enum tablespace_op_type tablespace_op)
3135
3180
{
3142
3187
    ALTER Table
3143
3188
  */
3144
3189
 
3145
 
  thd_proc_info(thd, "discard_or_import_tablespace");
 
3190
  session->set_proc_info("discard_or_import_tablespace");
3146
3191
 
3147
3192
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3148
3193
 
3150
3195
   We set this flag so that ha_innobase::open and ::external_lock() do
3151
3196
   not complain when we lock the table
3152
3197
 */
3153
 
  thd->tablespace_op= true;
3154
 
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
 
3198
  session->tablespace_op= true;
 
3199
  if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3155
3200
  {
3156
 
    thd->tablespace_op=false;
 
3201
    session->tablespace_op=false;
3157
3202
    return(-1);
3158
3203
  }
3159
3204
 
3160
3205
  error= table->file->ha_discard_or_import_tablespace(discard);
3161
3206
 
3162
 
  thd_proc_info(thd, "end");
 
3207
  session->set_proc_info("end");
3163
3208
 
3164
3209
  if (error)
3165
3210
    goto err;
3166
3211
 
3167
3212
  /* The ALTER Table is always in its own transaction */
3168
 
  error = ha_autocommit_or_rollback(thd, 0);
3169
 
  if (end_active_trans(thd))
 
3213
  error = ha_autocommit_or_rollback(session, 0);
 
3214
  if (end_active_trans(session))
3170
3215
    error=1;
3171
3216
  if (error)
3172
3217
    goto err;
3173
 
  write_bin_log(thd, false, thd->query, thd->query_length);
 
3218
  write_bin_log(session, false, session->query, session->query_length);
3174
3219
 
3175
3220
err:
3176
 
  ha_autocommit_or_rollback(thd, error);
3177
 
  thd->tablespace_op=false;
3178
 
  
 
3221
  ha_autocommit_or_rollback(session, error);
 
3222
  session->tablespace_op=false;
 
3223
 
3179
3224
  if (error == 0)
3180
3225
  {
3181
 
    my_ok(thd);
 
3226
    my_ok(session);
3182
3227
    return(0);
3183
3228
  }
3184
3229
 
3185
3230
  table->file->print_error(error, MYF(0));
3186
 
    
 
3231
 
3187
3232
  return(-1);
3188
3233
}
3189
3234
 
3223
3268
 
3224
3269
 
3225
3270
/**
3226
 
   @param       thd                Thread
 
3271
   @param       session                Thread
3227
3272
   @param       table              The original table.
3228
3273
   @param       alter_info         Alter options, fields and keys for the new
3229
3274
                                   table.
3255
3300
 
3256
3301
static
3257
3302
bool
3258
 
compare_tables(THD *thd,
 
3303
compare_tables(Session *session,
3259
3304
               Table *table,
3260
3305
               Alter_info *alter_info,
3261
3306
                           HA_CREATE_INFO *create_info,
3270
3315
  Create_field *new_field;
3271
3316
  KEY_PART_INFO *key_part;
3272
3317
  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
3318
 
3279
3319
  {
3280
3320
    /*
3292
3332
      to evaluate possibility of fast ALTER Table, and then
3293
3333
      destroy the copy.
3294
3334
    */
3295
 
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
3296
 
    THD *thd= table->in_use;
 
3335
    Alter_info tmp_alter_info(*alter_info, session->mem_root);
 
3336
    Session *session= table->in_use;
3297
3337
    uint32_t db_options= 0; /* not used */
3298
3338
    /* Create the prepared information. */
3299
 
    if (mysql_prepare_create_table(thd, create_info,
 
3339
    if (mysql_prepare_create_table(session, create_info,
3300
3340
                                   &tmp_alter_info,
3301
3341
                                   (table->s->tmp_table != NO_TMP_TABLE),
3302
3342
                                   &db_options,
3307
3347
      return(true);
3308
3348
    /* Allocate result buffers. */
3309
3349
    if (! (ha_alter_info->index_drop_buffer=
3310
 
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
 
3350
           (uint*) session->alloc(sizeof(uint) * table->s->keys)) ||
3311
3351
        ! (ha_alter_info->index_add_buffer=
3312
 
           (uint*) thd->alloc(sizeof(uint) *
 
3352
           (uint*) session->alloc(sizeof(uint) *
3313
3353
                              tmp_alter_info.key_list.elements)))
3314
3354
      return(true);
3315
3355
  }
3355
3395
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3356
3396
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3357
3397
      order_num ||
3358
 
      !table->s->mysql_version ||
3359
 
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
 
3398
      !table->s->mysql_version)
3360
3399
  {
3361
3400
    *table_changes= IS_EQUAL_NO;
3362
3401
    /*
3378
3417
    /* TODO check for ADD/DROP FOREIGN KEY */
3379
3418
    if (alter_info->flags & ALTER_FOREIGN_KEY)
3380
3419
      *alter_flags|=  HA_ALTER_FOREIGN_KEY;
3381
 
    if (!table->s->mysql_version ||
3382
 
        (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
3383
 
      *alter_flags|=  HA_ALTER_COLUMN_TYPE;
3384
3420
  }
3385
3421
  /*
3386
3422
    Go through fields and check if the original ones are compatible
3407
3443
      if (!(table_changes_local= field->is_equal(new_field)))
3408
3444
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3409
3445
 
 
3446
      /*
 
3447
        Check if the altered column is a stored virtual field.
 
3448
        TODO: Mark such a column with an alter flag only if
 
3449
        the expression functions are not equal.
 
3450
      */
 
3451
      if (field->is_stored && field->vcol_info)
 
3452
        *alter_flags|= HA_ALTER_STORED_VCOL;
 
3453
 
3410
3454
      /* Check if field was renamed */
3411
3455
      field->flags&= ~FIELD_IS_RENAMED;
3412
3456
      if (my_strcasecmp(system_charset_info,
3472
3516
      if (table_key->flags & HA_NOSAME)
3473
3517
      {
3474
3518
        /* Unique key. Check for "PRIMARY". */
3475
 
        if (! my_strcasecmp(system_charset_info,
3476
 
                            table_key->name, primary_key_name))
 
3519
        if (is_primary_key(table_key))
3477
3520
          *alter_flags|= HA_DROP_PK_INDEX;
3478
3521
        else
3479
3522
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
3493
3536
      if (table_key->flags & HA_NOSAME)
3494
3537
      {
3495
3538
        // Unique key. Check for "PRIMARY".
3496
 
        if (! my_strcasecmp(system_charset_info,
3497
 
                            table_key->name, primary_key_name))
 
3539
        if (is_primary_key(table_key))
3498
3540
          *alter_flags|= HA_ALTER_PK_INDEX;
3499
3541
        else
3500
3542
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3523
3565
        if (table_key->flags & HA_NOSAME)
3524
3566
        {
3525
3567
          /* Unique key. Check for "PRIMARY" */
3526
 
          if (! my_strcasecmp(system_charset_info,
3527
 
                              table_key->name, primary_key_name))
 
3568
          if (is_primary_key(table_key))
3528
3569
            *alter_flags|= HA_ALTER_PK_INDEX;
3529
3570
          else
3530
3571
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3586
3627
      if (new_key->flags & HA_NOSAME)
3587
3628
      {
3588
3629
        /* Unique key. Check for "PRIMARY" */
3589
 
        if (! my_strcasecmp(system_charset_info,
3590
 
                            new_key->name, primary_key_name))
 
3630
        if (is_primary_key(new_key))
3591
3631
          *alter_flags|= HA_ADD_PK_INDEX;
3592
3632
        else
3593
3633
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
3636
3676
 
3637
3677
  if (error == HA_ERR_WRONG_COMMAND)
3638
3678
  {
3639
 
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3679
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3640
3680
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3641
3681
                        table->s->table_name.str);
3642
3682
    error= 0;
3646
3686
  return(error);
3647
3687
}
3648
3688
 
3649
 
int create_temporary_table(THD *thd,
 
3689
int create_temporary_table(Session *session,
3650
3690
                           Table *table,
3651
3691
                           char *new_db,
3652
3692
                           char *tmp_name,
3688
3728
    if (create_info->index_file_name)
3689
3729
    {
3690
3730
      /* Fix index_file_name to have 'tmp_name' as basename */
3691
 
      my_stpcpy(index_file, tmp_name);
 
3731
      strcpy(index_file, tmp_name);
3692
3732
      create_info->index_file_name=fn_same(index_file,
3693
3733
                                           create_info->index_file_name,
3694
3734
                                           1);
3696
3736
    if (create_info->data_file_name)
3697
3737
    {
3698
3738
      /* Fix data_file_name to have 'tmp_name' as basename */
3699
 
      my_stpcpy(data_file, tmp_name);
 
3739
      strcpy(data_file, tmp_name);
3700
3740
      create_info->data_file_name=fn_same(data_file,
3701
3741
                                          create_info->data_file_name,
3702
3742
                                          1);
3707
3747
 
3708
3748
  /*
3709
3749
    Create a table with a temporary name.
3710
 
    With create_info->frm_only == 1 this creates a .frm file only.
3711
3750
    We don't log the statement, it will be logged later.
3712
3751
  */
3713
 
  tmp_disable_binlog(thd);
3714
 
  error= mysql_create_table(thd, new_db, tmp_name,
 
3752
  tmp_disable_binlog(session);
 
3753
  error= mysql_create_table(session, new_db, tmp_name,
3715
3754
                            create_info, alter_info, 1, 0);
3716
 
  reenable_binlog(thd);
 
3755
  reenable_binlog(session);
3717
3756
 
3718
3757
  return(error);
3719
3758
}
3724
3763
 
3725
3764
  SYNOPSIS
3726
3765
    create_altered_table()
3727
 
      thd              Thread handle
 
3766
      session              Thread handle
3728
3767
      table            The original table
3729
3768
      create_info      Information from the parsing phase about new
3730
3769
                       table properties.
3738
3777
    The temporary table is created without storing it in any storage engine
3739
3778
    and is opened only to get the table struct and frm file reference.
3740
3779
*/
3741
 
Table *create_altered_table(THD *thd,
 
3780
Table *create_altered_table(Session *session,
3742
3781
                            Table *table,
3743
3782
                            char *new_db,
3744
3783
                            HA_CREATE_INFO *create_info,
3751
3790
  char tmp_name[80];
3752
3791
  char path[FN_REFLEN];
3753
3792
 
3754
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3755
 
           tmp_file_prefix, current_pid, thd->thread_id);
 
3793
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
 
3794
           TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3756
3795
  /* Safety fix for InnoDB */
3757
3796
  if (lower_case_table_names)
3758
3797
    my_casedn_str(files_charset_info, tmp_name);
3759
3798
  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,
 
3799
 
 
3800
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
3762
3801
                                     &altered_create_info,
3763
3802
                                     alter_info, db_change)))
3764
3803
  {
3767
3806
 
3768
3807
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
3769
3808
                       FN_IS_TMP);
3770
 
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
 
3809
  altered_table= open_temporary_table(session, path, new_db, tmp_name, 1,
3771
3810
                                      OTM_ALTER);
3772
3811
  return(altered_table);
3773
3812
 
3780
3819
 
3781
3820
  SYNOPSIS
3782
3821
    mysql_fast_or_online_alter_table()
3783
 
      thd              Thread handle
 
3822
      session              Thread handle
3784
3823
      table            The original table
3785
3824
      altered_table    A temporary table showing how we will change table
3786
3825
      create_info      Information from the parsing phase about new
3800
3839
    operation directly, on-line without mysql having to copy
3801
3840
    the table.
3802
3841
*/
3803
 
int mysql_fast_or_online_alter_table(THD *thd,
 
3842
int mysql_fast_or_online_alter_table(Session *session,
3804
3843
                                     Table *table,
3805
3844
                                     Table *altered_table,
3806
3845
                                     HA_CREATE_INFO *create_info,
3817
3856
   /*
3818
3857
      Tell the handler to prepare for the online alter
3819
3858
    */
3820
 
    if ((error= table->file->alter_table_phase1(thd,
 
3859
    if ((error= table->file->alter_table_phase1(session,
3821
3860
                                                altered_table,
3822
3861
                                                create_info,
3823
3862
                                                alter_info,
3828
3867
 
3829
3868
    /*
3830
3869
       Tell the storage engine to perform the online alter table
3831
 
       TODO: 
 
3870
       TODO:
3832
3871
       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
3833
3872
       we need to wrap the next call with a DDL lock.
3834
3873
     */
3835
 
    if ((error= table->file->alter_table_phase2(thd,
 
3874
    if ((error= table->file->alter_table_phase2(session,
3836
3875
                                                altered_table,
3837
3876
                                                create_info,
3838
3877
                                                alter_info,
3846
3885
    and will be renamed to the original table name.
3847
3886
  */
3848
3887
  pthread_mutex_lock(&LOCK_open);
3849
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
3888
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3850
3889
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3851
3890
                          keys_onoff);
3852
 
  close_data_files_and_morph_locks(thd,
 
3891
  close_data_files_and_morph_locks(session,
3853
3892
                                   table->pos_in_table_list->db,
3854
3893
                                   table->pos_in_table_list->table_name);
3855
3894
  if (mysql_rename_table(NULL,
3871
3910
    wait_if_global_read_lock(), which could create a deadlock if called
3872
3911
    with LOCK_open.
3873
3912
  */
3874
 
  error= ha_autocommit_or_rollback(thd, 0);
 
3913
  error= ha_autocommit_or_rollback(session, 0);
3875
3914
 
3876
 
  if (ha_commit(thd))
 
3915
  if (ha_commit(session))
3877
3916
    error=1;
3878
3917
  if (error)
3879
3918
    goto err;
3892
3931
      Tell the handler that the changed frm is on disk and table
3893
3932
      has been re-opened
3894
3933
   */
3895
 
    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
 
3934
    if ((error= t_table->file->alter_table_phase3(session, t_table)))
3896
3935
    {
3897
3936
      goto err;
3898
3937
    }
3931
3970
  instructions that require change in table data, not only in
3932
3971
  table definition or indexes.
3933
3972
 
3934
 
  @param[in,out]  thd         thread handle. Used as a memory pool
 
3973
  @param[in,out]  session         thread handle. Used as a memory pool
3935
3974
                              and source of environment information.
3936
3975
  @param[in]      table       the source table, open and locked
3937
3976
                              Used as an interface to the storage engine
3958
3997
*/
3959
3998
 
3960
3999
static bool
3961
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
4000
mysql_prepare_alter_table(Session *session, Table *table,
3962
4001
                          HA_CREATE_INFO *create_info,
3963
4002
                          Alter_info *alter_info)
3964
4003
{
4044
4083
    if (def)
4045
4084
    {                                           // Field is changed
4046
4085
      def->field=field;
 
4086
      if (field->is_stored != def->is_stored)
 
4087
      {
 
4088
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
4089
                 MYF(0),
 
4090
                 "Changing the STORED status");
 
4091
        goto err;
 
4092
      }
4047
4093
      if (!def->after)
4048
4094
        {
4049
4095
        new_create_list.push_back(def);
4095
4141
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4096
4142
      flag to allow ALTER Table only if the table to be altered is empty.
4097
4143
      */
4098
 
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
 
4144
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4099
4145
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4100
4146
         !alter_info->datetime_field &&
4101
4147
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4102
 
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
 
4148
         session->variables.sql_mode & MODE_NO_ZERO_DATE)
4103
4149
    {
4104
4150
        alter_info->datetime_field= def;
4105
4151
        alter_info->error_if_not_empty= true;
4135
4181
      */
4136
4182
      if (alter_info->build_method == HA_BUILD_ONLINE)
4137
4183
      {
4138
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4184
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4139
4185
        goto err;
4140
4186
      }
4141
4187
      alter_info->build_method= HA_BUILD_OFFLINE;
4242
4288
 
4243
4289
      if (key_info->flags & HA_NOSAME)
4244
4290
      {
4245
 
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
 
4291
        if (is_primary_key_name(key_name))
4246
4292
          key_type= Key::PRIMARY;
4247
4293
        else
4248
4294
          key_type= Key::UNIQUE;
4261
4307
    Key *key;
4262
4308
    while ((key=key_it++))                      // Add new keys
4263
4309
    {
 
4310
      if (key->type == Key::FOREIGN_KEY &&
 
4311
          ((Foreign_key *)key)->validate(new_create_list))
 
4312
        goto err;
4264
4313
      if (key->type != Key::FOREIGN_KEY)
4265
4314
        new_key_list.push_back(key);
4266
 
      if (key->name.str &&
4267
 
          !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
 
4315
      if (key->name.str && is_primary_key_name(key->name.str))
4268
4316
      {
4269
4317
        my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
4270
4318
        goto err;
4321
4369
 
4322
4370
  SYNOPSIS
4323
4371
    mysql_alter_table()
4324
 
      thd              Thread handle
 
4372
      session              Thread handle
4325
4373
      new_db           If there is a RENAME clause
4326
4374
      new_name         If there is a RENAME clause
4327
4375
      create_info      Information from the parsing phase about new
4358
4406
    true   Error
4359
4407
*/
4360
4408
 
4361
 
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 
4409
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4362
4410
                       HA_CREATE_INFO *create_info,
4363
4411
                       TableList *table_list,
4364
4412
                       Alter_info *alter_info,
4365
4413
                       uint32_t order_num, order_st *order, bool ignore)
4366
4414
{
4367
4415
  Table *table, *new_table=0, *name_lock= 0;;
 
4416
  string new_name_str;
4368
4417
  int error= 0;
4369
4418
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4370
4419
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4371
4420
  char path[FN_REFLEN];
4372
4421
  ha_rows copied= 0,deleted= 0;
4373
4422
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4374
 
  legacy_db_type table_type;
 
4423
 
 
4424
  new_name_buff[0]= '\0';
4375
4425
 
4376
4426
  if (table_list && table_list->schema_table)
4377
4427
  {
4378
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
4428
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4379
4429
    return(true);
4380
4430
  }
4381
4431
 
4384
4434
    to simplify further comparisons: we want to see if it's a RENAME
4385
4435
    later just by comparing the pointers, avoiding the need for strcmp.
4386
4436
  */
4387
 
  thd_proc_info(thd, "init");
 
4437
  session->set_proc_info("init");
4388
4438
  table_name=table_list->table_name;
4389
4439
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4390
4440
  db=table_list->db;
4392
4442
    new_db= db;
4393
4443
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
4394
4444
 
4395
 
  mysql_ha_rm_tables(thd, table_list, false);
 
4445
  mysql_ha_rm_tables(session, table_list, false);
4396
4446
 
4397
4447
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4398
4448
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4399
4449
    /* Conditionally writes to binlog. */
4400
 
    return(mysql_discard_or_import_tablespace(thd,table_list,
 
4450
    return(mysql_discard_or_import_tablespace(session,table_list,
4401
4451
                                              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);
 
4452
  ostringstream oss;
 
4453
  oss << drizzle_data_home << "/" << db << "/" << table_name << reg_ext;
 
4454
 
 
4455
  (void) unpack_filename(new_name_buff, oss.str().c_str());
4405
4456
  /*
4406
4457
    If this is just a rename of a view, short cut to the
4407
4458
    following scenario: 1) lock LOCK_open 2) do a RENAME
4415
4466
    into the main table list, like open_tables does).
4416
4467
    This code is wrong and will be removed, please do not copy.
4417
4468
  */
4418
 
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
4419
4469
 
4420
 
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
 
4470
  if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4421
4471
    return(true);
4422
4472
  table->use_all_columns();
4423
4473
 
4424
4474
  /* Check that we are not trying to rename to an existing table */
4425
4475
  if (new_name)
4426
4476
  {
4427
 
    my_stpcpy(new_name_buff,new_name);
4428
 
    my_stpcpy(new_alias= new_alias_buff, new_name);
 
4477
    strcpy(new_name_buff,new_name);
 
4478
    strcpy(new_alias= new_alias_buff, new_name);
4429
4479
    if (lower_case_table_names)
4430
4480
    {
4431
4481
      if (lower_case_table_names != 2)
4432
4482
      {
4433
 
        my_casedn_str(files_charset_info, new_name_buff);
4434
 
        new_alias= new_name;                    // Create lower case table name
 
4483
        my_casedn_str(files_charset_info, new_name_buff);
 
4484
        new_alias= new_name;                    // Create lower case table name
4435
4485
      }
4436
4486
      my_casedn_str(files_charset_info, new_name);
4437
4487
    }
4448
4498
    {
4449
4499
      if (table->s->tmp_table != NO_TMP_TABLE)
4450
4500
      {
4451
 
        if (find_temporary_table(thd,new_db,new_name_buff))
 
4501
        if (find_temporary_table(session,new_db,new_name_buff))
4452
4502
        {
4453
4503
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
4454
4504
          return(true);
4456
4506
      }
4457
4507
      else
4458
4508
      {
4459
 
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
 
4509
        if (lock_table_name_if_not_cached(session, new_db, new_name, &name_lock))
4460
4510
          return(true);
4461
4511
        if (!name_lock)
4462
4512
        {
4487
4537
    create_info->db_type= old_db_type;
4488
4538
  }
4489
4539
 
4490
 
  if (check_engine(thd, new_name, create_info))
 
4540
  if (check_engine(session, new_name, create_info))
4491
4541
    goto err;
4492
4542
  new_db_type= create_info->db_type;
4493
4543
 
4502
4552
  if (create_info->row_type == ROW_TYPE_NOT_USED)
4503
4553
    create_info->row_type= table->s->row_type;
4504
4554
 
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))
 
4555
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_ALTER_NOT_SUPPORTED) ||
 
4556
      ha_check_storage_engine_flag(new_db_type, HTON_BIT_ALTER_NOT_SUPPORTED))
4507
4557
  {
4508
4558
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4509
4559
    goto err;
4510
4560
  }
4511
4561
 
4512
 
  thd_proc_info(thd, "setup");
 
4562
  session->set_proc_info("setup");
4513
4563
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4514
4564
      !table->s->tmp_table) // no need to touch frm
4515
4565
  {
4527
4577
        from concurrent DDL statements.
4528
4578
      */
4529
4579
      pthread_mutex_lock(&LOCK_open);
4530
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4580
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4531
4581
      pthread_mutex_unlock(&LOCK_open);
4532
4582
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4533
4583
      /* COND_refresh will be signaled in close_thread_tables() */
4534
4584
      break;
4535
4585
    case DISABLE:
4536
4586
      pthread_mutex_lock(&LOCK_open);
4537
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4587
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4538
4588
      pthread_mutex_unlock(&LOCK_open);
4539
4589
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4540
4590
      /* COND_refresh will be signaled in close_thread_tables() */
4547
4597
    if (error == HA_ERR_WRONG_COMMAND)
4548
4598
    {
4549
4599
      error= 0;
4550
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4600
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4551
4601
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4552
4602
                          table->alias);
4553
4603
    }
4564
4614
 
4565
4615
    if (!error && (new_name != table_name || new_db != db))
4566
4616
    {
4567
 
      thd_proc_info(thd, "rename");
 
4617
      session->set_proc_info("rename");
4568
4618
      /*
4569
4619
        Then do a 'simple' rename of the table. First we need to close all
4570
4620
        instances of 'source' table.
4571
4621
      */
4572
 
      close_cached_table(thd, table);
 
4622
      close_cached_table(session, table);
4573
4623
      /*
4574
4624
        Then, we want check once again that target table does not exist.
4575
4625
        Actually the order of these two steps does not matter since
4600
4650
    if (error == HA_ERR_WRONG_COMMAND)
4601
4651
  {
4602
4652
      error= 0;
4603
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4653
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4604
4654
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4605
4655
                          table->alias);
4606
4656
  }
4607
4657
 
4608
4658
    if (!error)
4609
4659
    {
4610
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4611
 
      my_ok(thd);
 
4660
      write_bin_log(session, true, session->query, session->query_length);
 
4661
      my_ok(session);
4612
4662
  }
4613
4663
    else if (error > 0)
4614
4664
  {
4616
4666
      error= -1;
4617
4667
    }
4618
4668
    if (name_lock)
4619
 
      unlink_open_table(thd, name_lock, false);
 
4669
      unlink_open_table(session, name_lock, false);
4620
4670
    pthread_mutex_unlock(&LOCK_open);
4621
4671
    table_list->table= NULL;                    // For query cache
4622
4672
    return(error);
4637
4687
  */
4638
4688
  new_db_type= create_info->db_type;
4639
4689
 
4640
 
  if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
 
4690
  if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4641
4691
      goto err;
4642
4692
 
4643
 
  set_table_default_charset(thd, create_info, db);
4644
 
 
4645
 
 
4646
 
  if (thd->variables.old_alter_table
 
4693
  set_table_default_charset(session, create_info, db);
 
4694
 
 
4695
 
 
4696
  if (session->variables.old_alter_table
4647
4697
      || (table->s->db_type() != create_info->db_type)
4648
4698
     )
4649
4699
  {
4650
4700
    if (alter_info->build_method == HA_BUILD_ONLINE)
4651
4701
    {
4652
 
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4702
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4653
4703
      goto err;
4654
4704
    }
4655
4705
    alter_info->build_method= HA_BUILD_OFFLINE;
4663
4713
    uint32_t table_changes= IS_EQUAL_YES;
4664
4714
    bool need_copy_table= true;
4665
4715
    /* Check how much the tables differ. */
4666
 
    if (compare_tables(thd, table, alter_info,
 
4716
    if (compare_tables(session, table, alter_info,
4667
4717
                       create_info, order_num,
4668
4718
                       &ha_alter_flags,
4669
4719
                       &ha_alter_info,
4686
4736
    if (new_name == table_name && new_db == db &&
4687
4737
        ha_alter_flags.is_set())
4688
4738
    {
4689
 
      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
 
4739
      Alter_info tmp_alter_info(*alter_info, session->mem_root);
4690
4740
 
4691
4741
      /*
4692
4742
        If no table rename,
4693
4743
        check if table can be altered on-line
4694
4744
      */
4695
 
      if (!(altered_table= create_altered_table(thd,
 
4745
      if (!(altered_table= create_altered_table(session,
4696
4746
                                                table,
4697
4747
                                                new_db,
4698
4748
                                                create_info,
4720
4770
      case HA_ALTER_NOT_SUPPORTED:
4721
4771
        if (alter_info->build_method == HA_BUILD_ONLINE)
4722
4772
        {
4723
 
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4724
 
          close_temporary_table(thd, altered_table, 1, 1);
 
4773
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
 
4774
          close_temporary_table(session, altered_table, 1, 1);
4725
4775
          goto err;
4726
4776
        }
4727
4777
        need_copy_table= true;
4728
4778
        break;
4729
4779
      case HA_ALTER_ERROR:
4730
4780
      default:
4731
 
        close_temporary_table(thd, altered_table, 1, 1);
 
4781
        close_temporary_table(session, altered_table, 1, 1);
4732
4782
        goto err;
4733
4783
      }
4734
4784
 
4739
4789
 
4740
4790
    if (!need_copy_table)
4741
4791
    {
4742
 
      error= mysql_fast_or_online_alter_table(thd,
 
4792
      error= mysql_fast_or_online_alter_table(session,
4743
4793
                                              table,
4744
4794
                                              altered_table,
4745
4795
                                              create_info,
4746
4796
                                              &ha_alter_info,
4747
4797
                                              &ha_alter_flags,
4748
4798
                                              alter_info->keys_onoff);
4749
 
      if (thd->lock)
 
4799
      if (session->lock)
4750
4800
      {
4751
 
        mysql_unlock_tables(thd, thd->lock);
4752
 
        thd->lock=0;
 
4801
        mysql_unlock_tables(session, session->lock);
 
4802
        session->lock=0;
4753
4803
      }
4754
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4804
      close_temporary_table(session, altered_table, 1, 1);
4755
4805
 
4756
4806
      if (error)
4757
4807
      {
4770
4820
    }
4771
4821
 
4772
4822
    if (altered_table)
4773
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4823
      close_temporary_table(session, altered_table, 1, 1);
4774
4824
  }
4775
4825
 
4776
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4777
 
           current_pid, thd->thread_id);
 
4826
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
 
4827
           (unsigned long)current_pid, session->thread_id);
4778
4828
  /* Safety fix for innodb */
4779
4829
  if (lower_case_table_names)
4780
4830
    my_casedn_str(files_charset_info, tmp_name);
4781
4831
 
4782
4832
 
4783
4833
  /* 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, 
 
4834
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
 
4835
                                     create_info, alter_info,
4786
4836
                                     !strcmp(db, new_db))))
4787
4837
  {
4788
4838
    goto err;
4795
4845
    memset(&tbl, 0, sizeof(tbl));
4796
4846
    tbl.db= new_db;
4797
4847
    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);
 
4848
    /* Table is in session->temporary_tables */
 
4849
    new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4800
4850
  }
4801
4851
  else
4802
4852
  {
4805
4855
    build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4806
4856
                         FN_IS_TMP);
4807
4857
    /* Open our intermediate table */
4808
 
    new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
 
4858
    new_table=open_temporary_table(session, path, new_db, tmp_name, 0, OTM_OPEN);
4809
4859
  }
4810
4860
  if (!new_table)
4811
4861
    goto err1;
4812
4862
 
4813
4863
  /* 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");
 
4864
  session->count_cuted_fields= CHECK_FIELD_WARN;        // calc cuted fields
 
4865
  session->cuted_fields=0L;
 
4866
  session->set_proc_info("copy to tmp table");
4817
4867
  copied=deleted=0;
4818
4868
  /*
4819
4869
    We do not copy data for MERGE tables. Only the children have data.
4833
4883
  else
4834
4884
  {
4835
4885
    pthread_mutex_lock(&LOCK_open);
4836
 
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4886
    wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4837
4887
    pthread_mutex_unlock(&LOCK_open);
4838
4888
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4839
4889
                            alter_info->keys_onoff);
4840
 
    error= ha_autocommit_or_rollback(thd, 0);
4841
 
    if (end_active_trans(thd))
 
4890
    error= ha_autocommit_or_rollback(session, 0);
 
4891
    if (end_active_trans(session))
4842
4892
      error= 1;
4843
4893
  }
4844
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
4894
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
4845
4895
 
4846
4896
  if (table->s->tmp_table != NO_TMP_TABLE)
4847
4897
  {
4849
4899
    if (error)
4850
4900
      goto err1;
4851
4901
    /* Close lock if this is a transactional table */
4852
 
    if (thd->lock)
 
4902
    if (session->lock)
4853
4903
    {
4854
 
      mysql_unlock_tables(thd, thd->lock);
4855
 
      thd->lock=0;
 
4904
      mysql_unlock_tables(session, session->lock);
 
4905
      session->lock=0;
4856
4906
    }
4857
4907
    /* Remove link to old table and rename the new one */
4858
 
    close_temporary_table(thd, table, 1, 1);
 
4908
    close_temporary_table(session, table, 1, 1);
4859
4909
    /* 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))
 
4910
    if (rename_temporary_table(session, new_table, new_db, new_name))
4861
4911
      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
4912
    goto end_temporary;
4866
4913
  }
4867
4914
 
4898
4945
       call to remove name-locks from table cache and list of open table.
4899
4946
  */
4900
4947
 
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);
 
4948
  session->set_proc_info("rename result table");
 
4949
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
 
4950
           (unsigned long)current_pid, session->thread_id);
4904
4951
  if (lower_case_table_names)
4905
4952
    my_casedn_str(files_charset_info, old_name);
4906
4953
 
4907
 
  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4908
 
  close_data_files_and_morph_locks(thd, db, table_name);
 
4954
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
 
4955
  close_data_files_and_morph_locks(session, db, table_name);
4909
4956
 
4910
4957
  error=0;
4911
4958
  save_old_db_type= old_db_type;
4949
4996
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4950
4997
 
4951
4998
end_online:
4952
 
  if (thd->locked_tables && new_name == table_name && new_db == db)
 
4999
  if (session->locked_tables && new_name == table_name && new_db == db)
4953
5000
  {
4954
 
    thd->in_lock_tables= 1;
4955
 
    error= reopen_tables(thd, 1, 1);
4956
 
    thd->in_lock_tables= 0;
 
5001
    session->in_lock_tables= 1;
 
5002
    error= reopen_tables(session, 1, 1);
 
5003
    session->in_lock_tables= 0;
4957
5004
    if (error)
4958
5005
      goto err_with_placeholders;
4959
5006
  }
4960
5007
  pthread_mutex_unlock(&LOCK_open);
4961
5008
 
4962
 
  thd_proc_info(thd, "end");
 
5009
  session->set_proc_info("end");
4963
5010
 
4964
 
  assert(!(mysql_bin_log.is_open() &&
4965
 
                thd->current_stmt_binlog_row_based &&
 
5011
  assert(!(drizzle_bin_log.is_open() &&
4966
5012
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4967
 
  write_bin_log(thd, true, thd->query, thd->query_length);
 
5013
  write_bin_log(session, true, session->query, session->query_length);
4968
5014
 
4969
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
 
5015
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
4970
5016
  {
4971
5017
    /*
4972
5018
      For the alter table to be properly flushed to the logs, we
4976
5022
    char path[FN_REFLEN];
4977
5023
    Table *t_table;
4978
5024
    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);
 
5025
    t_table= open_temporary_table(session, path, new_db, tmp_name, false, OTM_OPEN);
4980
5026
    if (t_table)
4981
5027
    {
4982
5028
      intern_close_table(t_table);
4989
5035
  }
4990
5036
  table_list->table=0;                          // For query cache
4991
5037
 
4992
 
  if (thd->locked_tables && (new_name != table_name || new_db != db))
 
5038
  if (session->locked_tables && (new_name != table_name || new_db != db))
4993
5039
  {
4994
5040
    /*
4995
5041
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
4998
5044
      LOCK TABLES we can rely on close_thread_tables() doing this job.
4999
5045
    */
5000
5046
    pthread_mutex_lock(&LOCK_open);
5001
 
    unlink_open_table(thd, table, false);
5002
 
    unlink_open_table(thd, name_lock, false);
 
5047
    unlink_open_table(session, table, false);
 
5048
    unlink_open_table(session, name_lock, false);
5003
5049
    pthread_mutex_unlock(&LOCK_open);
5004
5050
  }
5005
5051
 
5006
5052
end_temporary:
5007
5053
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5008
5054
           (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;
 
5055
           (ulong) session->cuted_fields);
 
5056
  my_ok(session, copied + deleted, 0L, tmp_name);
 
5057
  session->some_tables_deleted=0;
5012
5058
  return(false);
5013
5059
 
5014
5060
err1:
5015
5061
  if (new_table)
5016
5062
  {
5017
5063
    /* close_temporary_table() frees the new_table pointer. */
5018
 
    close_temporary_table(thd, new_table, 1, 1);
 
5064
    close_temporary_table(session, new_table, 1, 1);
5019
5065
  }
5020
5066
  else
5021
5067
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5027
5073
    the table to be altered isn't empty.
5028
5074
    Report error here.
5029
5075
  */
5030
 
  if (alter_info->error_if_not_empty && thd->row_count)
 
5076
  if (alter_info->error_if_not_empty && session->row_count)
5031
5077
  {
5032
5078
    const char *f_val= 0;
5033
5079
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
5034
5080
    switch (alter_info->datetime_field->sql_type)
5035
5081
    {
5036
 
      case DRIZZLE_TYPE_NEWDATE:
 
5082
      case DRIZZLE_TYPE_DATE:
5037
5083
        f_val= "0000-00-00";
5038
5084
        t_type= DRIZZLE_TIMESTAMP_DATE;
5039
5085
        break;
5045
5091
        /* Shouldn't get here. */
5046
5092
        assert(0);
5047
5093
    }
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,
 
5094
    bool save_abort_on_warning= session->abort_on_warning;
 
5095
    session->abort_on_warning= true;
 
5096
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5051
5097
                                 f_val, strlength(f_val), t_type,
5052
5098
                                 alter_info->datetime_field->field_name);
5053
 
    thd->abort_on_warning= save_abort_on_warning;
 
5099
    session->abort_on_warning= save_abort_on_warning;
5054
5100
  }
5055
5101
  if (name_lock)
5056
5102
  {
5057
5103
    pthread_mutex_lock(&LOCK_open);
5058
 
    unlink_open_table(thd, name_lock, false);
 
5104
    unlink_open_table(session, name_lock, false);
5059
5105
    pthread_mutex_unlock(&LOCK_open);
5060
5106
  }
5061
5107
  return(true);
5066
5112
    being altered. To be safe under LOCK TABLES we should remove placeholders
5067
5113
    from list of open tables list and table cache.
5068
5114
  */
5069
 
  unlink_open_table(thd, table, false);
 
5115
  unlink_open_table(session, table, false);
5070
5116
  if (name_lock)
5071
 
    unlink_open_table(thd, name_lock, false);
 
5117
    unlink_open_table(session, name_lock, false);
5072
5118
  pthread_mutex_unlock(&LOCK_open);
5073
5119
  return(true);
5074
5120
}
5087
5133
  int error;
5088
5134
  Copy_field *copy,*copy_end;
5089
5135
  ulong found_count,delete_count;
5090
 
  THD *thd= current_thd;
 
5136
  Session *session= current_session;
5091
5137
  uint32_t length= 0;
5092
5138
  SORT_FIELD *sortorder;
5093
5139
  READ_RECORD info;
5102
5148
  /*
5103
5149
    Turn off recovery logging since rollback of an alter table is to
5104
5150
    delete the new table so there is no need to log the changes to it.
5105
 
    
 
5151
 
5106
5152
    This needs to be done before external_lock
5107
5153
  */
5108
 
  error= ha_enable_transaction(thd, false);
 
5154
  error= ha_enable_transaction(session, false);
5109
5155
  if (error)
5110
5156
    return(-1);
5111
 
  
 
5157
 
5112
5158
  if (!(copy= new Copy_field[to->s->fields]))
5113
5159
    return(-1);                         /* purecov: inspected */
5114
5160
 
5115
 
  if (to->file->ha_external_lock(thd, F_WRLCK))
 
5161
  if (to->file->ha_external_lock(session, F_WRLCK))
5116
5162
    return(-1);
5117
5163
 
5118
5164
  /* We need external lock before we can disable/enable keys */
5119
5165
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5120
5166
 
5121
5167
  /* We can abort alter table for any table type */
5122
 
  thd->abort_on_warning= !ignore;
 
5168
  session->abort_on_warning= !ignore;
5123
5169
 
5124
5170
  from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5125
5171
  to->file->ha_start_bulk_insert(from->file->stats.records);
5126
5172
 
5127
 
  save_sql_mode= thd->variables.sql_mode;
 
5173
  save_sql_mode= session->variables.sql_mode;
5128
5174
 
5129
5175
  List_iterator<Create_field> it(create);
5130
5176
  Create_field *def;
5149
5195
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5150
5196
    {
5151
5197
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
5152
 
      snprintf(warn_buff, sizeof(warn_buff), 
 
5198
      snprintf(warn_buff, sizeof(warn_buff),
5153
5199
               _("order_st BY ignored because there is a user-defined clustered "
5154
5200
                 "index in the table '%-.192s'"),
5155
5201
               from->s->table_name.str);
5156
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
5202
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5157
5203
                   warn_buff);
5158
5204
    }
5159
5205
    else
5160
5206
    {
5161
 
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5162
 
                                                MYF(MY_FAE | MY_ZEROFILL));
 
5207
      from->sort.io_cache= new IO_CACHE;
 
5208
      memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
 
5209
 
5163
5210
      memset(&tables, 0, sizeof(tables));
5164
5211
      tables.table= from;
5165
5212
      tables.alias= tables.table_name= from->s->table_name.str;
5166
5213
      tables.db= from->s->db.str;
5167
5214
      error= 1;
5168
5215
 
5169
 
      if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5170
 
          setup_order(thd, thd->lex->select_lex.ref_pointer_array,
 
5216
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
 
5217
          setup_order(session, session->lex->select_lex.ref_pointer_array,
5171
5218
                      &tables, fields, all_fields, order) ||
5172
5219
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5173
 
          (from->sort.found_records= filesort(thd, from, sortorder, length,
 
5220
          (from->sort.found_records= filesort(session, from, sortorder, length,
5174
5221
                                              (SQL_SELECT *) 0, HA_POS_ERROR,
5175
5222
                                              1, &examined_rows)) ==
5176
5223
          HA_POS_ERROR)
5180
5227
 
5181
5228
  /* Tell handler that we have values for all columns in the to table */
5182
5229
  to->use_all_columns();
5183
 
  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
 
5230
  init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
5184
5231
  if (ignore)
5185
5232
    to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5186
 
  thd->row_count= 0;
 
5233
  session->row_count= 0;
5187
5234
  restore_record(to, s->default_values);        // Create empty record
5188
5235
  while (!(error=info.read_record(&info)))
5189
5236
  {
5190
 
    if (thd->killed)
 
5237
    if (session->killed)
5191
5238
    {
5192
 
      thd->send_kill_message();
 
5239
      session->send_kill_message();
5193
5240
      error= 1;
5194
5241
      break;
5195
5242
    }
5196
 
    thd->row_count++;
 
5243
    session->row_count++;
5197
5244
    /* Return error if source table isn't empty. */
5198
5245
    if (error_if_not_empty)
5199
5246
    {
5207
5254
      else
5208
5255
        to->next_number_field->reset();
5209
5256
    }
5210
 
    
 
5257
 
5211
5258
    for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
5212
5259
    {
5213
5260
      copy_ptr->do_copy(copy_ptr);
5214
5261
    }
5215
5262
    prev_insert_id= to->file->next_insert_id;
 
5263
    update_virtual_fields_marked_for_write(to, false);
5216
5264
    error=to->file->ha_write_row(to->record[0]);
5217
5265
    to->auto_increment_field_not_null= false;
5218
5266
    if (error)
5255
5303
  }
5256
5304
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
5257
5305
 
5258
 
  if (ha_enable_transaction(thd, true))
 
5306
  if (ha_enable_transaction(session, true))
5259
5307
  {
5260
5308
    error= 1;
5261
5309
    goto err;
5265
5313
    Ensure that the new table is saved properly to disk so that we
5266
5314
    can do a rename
5267
5315
  */
5268
 
  if (ha_autocommit_or_rollback(thd, 0))
 
5316
  if (ha_autocommit_or_rollback(session, 0))
5269
5317
    error=1;
5270
 
  if (end_active_trans(thd))
 
5318
  if (end_active_trans(session))
5271
5319
    error=1;
5272
5320
 
5273
5321
 err:
5274
 
  thd->variables.sql_mode= save_sql_mode;
5275
 
  thd->abort_on_warning= 0;
 
5322
  session->variables.sql_mode= save_sql_mode;
 
5323
  session->abort_on_warning= 0;
5276
5324
  free_io_cache(from);
5277
5325
  *copied= found_count;
5278
5326
  *deleted=delete_count;
5279
5327
  to->file->ha_release_auto_increment();
5280
 
  if (to->file->ha_external_lock(thd,F_UNLCK))
 
5328
  if (to->file->ha_external_lock(session,F_UNLCK))
5281
5329
    error=1;
5282
5330
  return(error > 0 ? -1 : 0);
5283
5331
}
5288
5336
 
5289
5337
  SYNOPSIS
5290
5338
    mysql_recreate_table()
5291
 
    thd                 Thread handler
 
5339
    session                     Thread handler
5292
5340
    tables              Tables to recreate
5293
5341
 
5294
5342
 RETURN
5295
5343
    Like mysql_alter_table().
5296
5344
*/
5297
 
bool mysql_recreate_table(THD *thd, TableList *table_list)
 
5345
bool mysql_recreate_table(Session *session, TableList *table_list)
5298
5346
{
5299
5347
  HA_CREATE_INFO create_info;
5300
5348
  Alter_info alter_info;
5311
5359
  create_info.default_table_charset=default_charset_info;
5312
5360
  /* Force alter table to recreate table */
5313
5361
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5314
 
  return(mysql_alter_table(thd, NULL, NULL, &create_info,
 
5362
  return(mysql_alter_table(session, NULL, NULL, &create_info,
5315
5363
                                table_list, &alter_info, 0,
5316
5364
                                (order_st *) 0, 0));
5317
5365
}
5318
5366
 
5319
5367
 
5320
 
bool mysql_checksum_table(THD *thd, TableList *tables,
 
5368
bool mysql_checksum_table(Session *session, TableList *tables,
5321
5369
                          HA_CHECK_OPT *check_opt)
5322
5370
{
5323
5371
  TableList *table;
5324
5372
  List<Item> field_list;
5325
5373
  Item *item;
5326
 
  Protocol *protocol= thd->protocol;
 
5374
  Protocol *protocol= session->protocol;
5327
5375
 
5328
5376
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5329
5377
  item->maybe_null= 1;
5340
5388
    char table_name[NAME_LEN*2+2];
5341
5389
    Table *t;
5342
5390
 
5343
 
    strxmov(table_name, table->db ,".", table->table_name, NULL);
 
5391
    sprintf(table_name,"%s.%s",table->db,table->table_name);
5344
5392
 
5345
 
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5346
 
    thd->clear_error();                 // these errors shouldn't get client
 
5393
    t= table->table= open_n_lock_single_table(session, table, TL_READ);
 
5394
    session->clear_error();                     // these errors shouldn't get client
5347
5395
 
5348
5396
    protocol->prepare_for_resend();
5349
5397
    protocol->store(table_name, system_charset_info);
5352
5400
    {
5353
5401
      /* Table didn't exist */
5354
5402
      protocol->store_null();
5355
 
      thd->clear_error();
 
5403
      session->clear_error();
5356
5404
    }
5357
5405
    else
5358
5406
    {
5415
5463
          t->file->ha_rnd_end();
5416
5464
        }
5417
5465
      }
5418
 
      thd->clear_error();
5419
 
      close_thread_tables(thd);
 
5466
      session->clear_error();
 
5467
      close_thread_tables(session);
5420
5468
      table->table=0;                           // For query cache
5421
5469
    }
5422
5470
    if (protocol->write())
5423
5471
      goto err;
5424
5472
  }
5425
5473
 
5426
 
  my_eof(thd);
 
5474
  my_eof(session);
5427
5475
  return(false);
5428
5476
 
5429
5477
 err:
5430
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
5478
  close_thread_tables(session);                 // Shouldn't be needed
5431
5479
  if (table)
5432
5480
    table->table=0;
5433
5481
  return(true);
5434
5482
}
5435
5483
 
5436
 
static bool check_engine(THD *thd, const char *table_name,
 
5484
static bool check_engine(Session *session, const char *table_name,
5437
5485
                         HA_CREATE_INFO *create_info)
5438
5486
{
5439
5487
  handlerton **new_engine= &create_info->db_type;
5440
5488
  handlerton *req_engine= *new_engine;
5441
5489
  bool no_substitution= 1;
5442
 
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
 
5490
  if (!(*new_engine= ha_checktype(session, ha_legacy_type(req_engine),
5443
5491
                                  no_substitution, 1)))
5444
5492
    return true;
5445
5493
 
5446
5494
  if (req_engine && req_engine != *new_engine)
5447
5495
  {
5448
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5496
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5449
5497
                       ER_WARN_USING_OTHER_HANDLER,
5450
5498
                       ER(ER_WARN_USING_OTHER_HANDLER),
5451
5499
                       ha_resolve_storage_engine_name(*new_engine),
5452
5500
                       table_name);
5453
5501
  }
5454
5502
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5455
 
      ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
 
5503
      ha_check_storage_engine_flag(*new_engine, HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5456
5504
  {
5457
5505
    if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5458
5506
    {