~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2009-02-20 22:48:37 UTC
  • Revision ID: brian@tangent.org-20090220224837-fw5wrf46n4ru3e6a
First pass of stripping uint

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
#include <drizzled/server_includes.h>
19
19
#include <storage/myisam/myisam.h>
20
 
#include <drizzled/sql_show.h>
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
#include <libdrizzle/gettext.h>
 
20
#include <drizzled/show.h>
 
21
#include <drizzled/error.h>
 
22
#include <drizzled/gettext.h>
 
23
#include <drizzled/data_home.h>
 
24
#include <drizzled/sql_parse.h>
 
25
#include <mysys/hash.h>
 
26
#include <drizzled/sql_lex.h>
 
27
#include <drizzled/session.h>
 
28
#include <drizzled/sql_base.h>
 
29
#include <drizzled/db.h>
 
30
#include <drizzled/lock.h>
 
31
#include <drizzled/unireg.h>
 
32
#include <drizzled/item/int.h>
 
33
#include <drizzled/item/empty_string.h>
 
34
#include <drizzled/replicator.h>
 
35
 
 
36
using namespace std;
 
37
 
 
38
extern HASH lock_db_cache;
23
39
 
24
40
int creating_table= 0;        // How many mysql_create_table are running
25
41
 
26
 
const char *primary_key_name="PRIMARY";
 
42
 
 
43
bool is_primary_key(KEY *key_info)
 
44
{
 
45
  static const char * primary_key_name="PRIMARY";
 
46
  return (strcmp(key_info->name, primary_key_name)==0);
 
47
}
 
48
 
 
49
const char* is_primary_key_name(const char* key_name)
 
50
{
 
51
  static const char * primary_key_name="PRIMARY";
 
52
  if (strcmp(key_name, primary_key_name)==0)
 
53
    return key_name;
 
54
  else
 
55
    return NULL;
 
56
}
27
57
 
28
58
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
59
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
34
64
                                    enum enum_enable_or_disable keys_onoff,
35
65
                                    bool error_if_not_empty);
36
66
 
37
 
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
38
 
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
 
67
static bool prepare_blob_field(Session *session, Create_field *sql_field);
 
68
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
39
69
static int
40
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
70
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
41
71
                           Alter_info *alter_info,
42
72
                           bool tmp_table,
43
73
                               uint32_t *db_options,
44
74
                               handler *file, KEY **key_info_buffer,
45
75
                               uint32_t *key_count, int select_field_count);
46
76
static bool
47
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
77
mysql_prepare_alter_table(Session *session, Table *table,
48
78
                          HA_CREATE_INFO *create_info,
49
79
                          Alter_info *alter_info);
50
80
 
 
81
static void set_table_default_charset(Session *session,
 
82
                                      HA_CREATE_INFO *create_info, char *db)
 
83
{
 
84
  /*
 
85
    If the table character set was not given explicitly,
 
86
    let's fetch the database default character set and
 
87
    apply it to the table.
 
88
  */
 
89
  if (!create_info->default_table_charset)
 
90
  {
 
91
    HA_CREATE_INFO db_info;
 
92
 
 
93
    load_db_opt_by_name(session, db, &db_info);
 
94
 
 
95
    create_info->default_table_charset= db_info.default_table_charset;
 
96
  }
 
97
}
 
98
 
51
99
/*
52
100
  Translate a file name to a table name (WL #1324).
53
101
 
65
113
  uint32_t errors;
66
114
  uint32_t res;
67
115
 
68
 
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
 
116
  if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
69
117
  {
70
118
    /* Temporary table name. */
71
 
    res= (my_stpncpy(to, from, to_length) - to);
 
119
    res= strlen(strncpy(to, from, to_length));
72
120
  }
73
121
  else
74
122
  {
76
124
                    system_charset_info,  to, to_length, &errors);
77
125
    if (errors) // Old 5.0 name
78
126
    {
79
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NULL) -
80
 
            to);
81
 
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
 
127
      strcpy(to, MYSQL50_TABLE_NAME_PREFIX);
 
128
      strncat(to, from, to_length-MYSQL50_TABLE_NAME_PREFIX_LENGTH-1);
 
129
      res= strlen(to);
 
130
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid (old?) table or database name '%s'"), from);
82
131
    }
83
132
  }
84
133
 
98
147
  RETURN
99
148
    File name length.
100
149
*/
101
 
 
102
150
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
103
151
{
104
152
  uint32_t errors, length;
105
153
 
106
154
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
107
155
                                 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)));
 
156
    return((uint) (strncpy(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
 
157
                           to_length-1) -
 
158
                           (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
111
159
  length= strconvert(system_charset_info, from,
112
160
                     &my_charset_filename, to, to_length, &errors);
113
161
  if (check_if_legal_tablename(to) &&
121
169
 
122
170
 
123
171
/*
124
 
  Creates path to a file: mysql_data_dir/db/table.ext
 
172
  Creates path to a file: drizzle_data_dir/db/table.ext
125
173
 
126
174
  SYNOPSIS
127
175
   build_table_filename()
137
185
  NOTES
138
186
 
139
187
    Uses database and table name, and extension to create
140
 
    a file name in mysql_data_dir. Database and table
 
188
    a file name in drizzle_data_dir. Database and table
141
189
    names are converted from system_charset_info into "fscs".
142
190
    Unless flags indicate a temporary table name.
143
191
    'db' is always converted.
150
198
    build_tmptable_filename() for them.
151
199
 
152
200
  RETURN
153
 
    path length
 
201
    path length on success, 0 on failure
154
202
*/
155
203
 
156
204
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
157
205
                          const char *table_name, const char *ext, uint32_t flags)
158
206
{
 
207
  string table_path;
159
208
  char dbbuff[FN_REFLEN];
160
209
  char tbbuff[FN_REFLEN];
 
210
  int rootdir_len= strlen(FN_ROOTDIR);
161
211
 
162
212
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
 
    my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
 
213
    strncpy(tbbuff, table_name, sizeof(tbbuff));
164
214
  else
165
215
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
166
216
 
167
217
  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);
 
218
  table_path= drizzle_data_home;
 
219
  int without_rootdir= table_path.length()-rootdir_len;
 
220
 
 
221
  /* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
 
222
  if (without_rootdir >= 0)
 
223
  {
 
224
    char *tmp= (char*)table_path.c_str()+without_rootdir;
 
225
    if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
 
226
      table_path.append(FN_ROOTDIR);
 
227
  }
 
228
 
 
229
  table_path.append(dbbuff);
 
230
  table_path.append(FN_ROOTDIR);
177
231
#ifdef USE_SYMDIR
178
 
  unpack_dirname(buff, buff);
179
 
  pos= strend(buff);
 
232
  table_path.clear();
180
233
#endif
181
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
182
 
 
183
 
  return(pos - buff);
 
234
  table_path.append(tbbuff);
 
235
  table_path.append(ext);
 
236
 
 
237
  if (bufflen < table_path.length())
 
238
    return 0;
 
239
 
 
240
  strcpy(buff, table_path.c_str());
 
241
  return table_path.length();
184
242
}
185
243
 
186
244
 
187
245
/*
188
 
  Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
 
246
  Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
189
247
 
190
248
  SYNOPSIS
191
249
   build_tmptable_filename()
192
 
     thd                        The thread handle.
 
250
     session                    The thread handle.
193
251
     buff                       Where to write result in my_charset_filename.
194
252
     bufflen                    buff size
195
253
 
196
254
  NOTES
197
255
 
198
256
    Uses current_pid, thread_id, and tmp_table counter to create
199
 
    a file name in mysql_tmpdir.
 
257
    a file name in drizzle_tmpdir.
200
258
 
201
259
  RETURN
202
 
    path length
 
260
    path length on success, 0 on failure
203
261
*/
204
262
 
205
 
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
263
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
206
264
{
 
265
  uint32_t length;
 
266
  ostringstream path_str, post_tmpdir_str;
 
267
  string tmp;
207
268
 
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);
 
269
  path_str << drizzle_tmpdir;
 
270
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
 
271
  post_tmpdir_str << session->thread_id << session->tmp_table++ << reg_ext;
 
272
  tmp= post_tmpdir_str.str();
212
273
 
213
274
  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);
 
275
    transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
 
276
 
 
277
  path_str << tmp;
 
278
 
 
279
  if (bufflen < path_str.str().length())
 
280
    length= 0;
 
281
  else
 
282
    length= unpack_filename(buff, path_str.str().c_str());
 
283
 
 
284
  return length;
221
285
}
222
286
 
223
287
/*
224
288
  SYNOPSIS
225
289
    write_bin_log()
226
 
    thd                           Thread object
 
290
    session                           Thread object
227
291
    clear_error                   is clear_error to be called
228
292
    query                         Query to log
229
293
    query_length                  Length of query
236
300
    file
237
301
*/
238
302
 
239
 
void write_bin_log(THD *thd, bool clear_error,
240
 
                   char const *query, ulong query_length)
 
303
void write_bin_log(Session *session, bool,
 
304
                   char const *query, size_t query_length)
241
305
{
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
 
  }
 
306
  (void)replicator_statement(session, query, query_length);
249
307
}
250
308
 
251
309
 
254
312
 
255
313
  SYNOPSIS
256
314
   mysql_rm_table()
257
 
   thd                  Thread handle
 
315
   session                      Thread handle
258
316
   tables               List of tables to delete
259
317
   if_exists            If 1, don't give error if one table doesn't exists
260
318
 
273
331
 
274
332
*/
275
333
 
276
 
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
 
334
bool mysql_rm_table(Session *session,TableList *tables, bool if_exists, bool drop_temporary)
277
335
{
278
336
  bool error, need_start_waiting= false;
279
337
 
280
338
  if (tables && tables->schema_table)
281
339
  {
282
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
340
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
283
341
    return(true);
284
342
  }
285
343
 
287
345
 
288
346
  if (!drop_temporary)
289
347
  {
290
 
    if (!thd->locked_tables &&
291
 
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
348
    if (!session->locked_tables &&
 
349
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
292
350
      return(true);
293
351
  }
294
352
 
297
355
    LOCK_open during wait_if_global_read_lock(), other threads could not
298
356
    close their tables. This would make a pretty deadlock.
299
357
  */
300
 
  error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
 
358
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0);
301
359
 
302
360
  if (need_start_waiting)
303
 
    start_waiting_global_read_lock(thd);
 
361
    start_waiting_global_read_lock(session);
304
362
 
305
363
  if (error)
306
364
    return(true);
307
 
  my_ok(thd);
 
365
  session->my_ok();
308
366
  return(false);
309
367
}
310
368
 
313
371
 
314
372
  SYNOPSIS
315
373
    mysql_rm_table_part2()
316
 
    thd                 Thread handler
 
374
    session                     Thread handler
317
375
    tables              Tables to drop
318
376
    if_exists           If set, don't give an error if table doesn't exists.
319
377
                        In this case we give an warning of level 'NOTE'
320
378
    drop_temporary      Only drop temporary tables
321
379
    drop_view           Allow to delete VIEW .frm
322
380
    dont_log_query      Don't write query to log files. This will also not
323
 
                        generate warnings if the handler files doesn't exists  
 
381
                        generate warnings if the handler files doesn't exists
324
382
 
325
383
  TODO:
326
384
    When logging to the binary log, we should log
338
396
   -1   Thread was killed
339
397
*/
340
398
 
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)
 
399
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
 
400
                         bool drop_temporary, bool dont_log_query)
344
401
{
345
402
  TableList *table;
346
403
  char path[FN_REFLEN], *alias;
347
 
  uint32_t path_length;
 
404
  uint32_t path_length= 0;
348
405
  String wrong_tables;
349
406
  int error= 0;
350
407
  int non_temp_tables_count= 0;
351
408
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
352
409
  String built_query;
353
410
 
354
 
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
411
  if (!dont_log_query)
355
412
  {
356
413
    built_query.set_charset(system_charset_info);
357
414
    if (if_exists)
360
417
      built_query.append("DROP Table ");
361
418
  }
362
419
 
363
 
  mysql_ha_rm_tables(thd, tables, false);
 
420
  mysql_ha_rm_tables(session, tables, false);
364
421
 
365
422
  pthread_mutex_lock(&LOCK_open);
366
423
 
378
435
      table->db_type= share->db_type();
379
436
  }
380
437
 
381
 
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
 
438
  if (!drop_temporary && lock_table_names_exclusively(session, tables))
382
439
  {
383
440
    pthread_mutex_unlock(&LOCK_open);
384
441
    return(1);
385
442
  }
386
443
 
387
444
  /* Don't give warnings for not found errors, as we already generate notes */
388
 
  thd->no_warnings_for_error= 1;
 
445
  session->no_warnings_for_error= 1;
389
446
 
390
447
  for (table= tables; table; table= table->next_local)
391
448
  {
392
449
    char *db=table->db;
393
450
    handlerton *table_type;
394
 
    enum legacy_db_type frm_db_type;
395
 
 
396
 
 
397
 
    error= drop_temporary_table(thd, table);
 
451
 
 
452
    error= drop_temporary_table(session, table);
398
453
 
399
454
    switch (error) {
400
455
    case  0:
402
457
      tmp_table_deleted= 1;
403
458
      continue;
404
459
    case -1:
405
 
      assert(thd->in_sub_stmt);
406
460
      error= 1;
407
461
      goto err_with_placeholders;
408
462
    default:
416
470
      being built.  The string always end in a comma and the comma
417
471
      will be chopped off before being written to the binary log.
418
472
      */
419
 
    if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
473
    if (!dont_log_query)
420
474
    {
421
475
      non_temp_tables_count++;
422
476
      /*
423
477
        Don't write the database name if it is the current one (or if
424
 
        thd->db is NULL).
 
478
        session->db is NULL).
425
479
      */
426
480
      built_query.append("`");
427
 
      if (thd->db == NULL || strcmp(db,thd->db) != 0)
 
481
      if (session->db == NULL || strcmp(db,session->db) != 0)
428
482
      {
429
483
        built_query.append(db);
430
484
        built_query.append("`.`");
438
492
    if (!drop_temporary)
439
493
    {
440
494
      Table *locked_table;
441
 
      abort_locked_tables(thd, db, table->table_name);
442
 
      remove_table_from_cache(thd, db, table->table_name,
 
495
      abort_locked_tables(session, db, table->table_name);
 
496
      remove_table_from_cache(session, db, table->table_name,
443
497
                              RTFC_WAIT_OTHER_THREAD_FLAG |
444
498
                              RTFC_CHECK_KILLED_FLAG);
445
499
      /*
446
500
        If the table was used in lock tables, remember it so that
447
501
        unlock_table_names can free it
448
502
      */
449
 
      if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
 
503
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
450
504
        table->table= locked_table;
451
505
 
452
 
      if (thd->killed)
 
506
      if (session->killed)
453
507
      {
454
508
        error= -1;
455
509
        goto err_with_placeholders;
461
515
                                        FN_IS_TMP : 0);
462
516
    }
463
517
    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)))
 
518
        ((table_type == NULL && (access(path, F_OK))))
 
519
        )
466
520
    {
467
521
      // Table was not found on disk and table can't be created from engine
468
522
      if (if_exists)
469
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
523
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
470
524
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
471
525
                            table->table_name);
472
526
      else
475
529
    else
476
530
    {
477
531
      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
532
      // Remove extension for delete
484
533
      *(end= path + path_length - reg_ext_length)= '\0';
485
 
      error= ha_delete_table(thd, table_type, path, db, table->table_name,
 
534
      error= ha_delete_table(session, path, db, table->table_name,
486
535
                             !dont_log_query);
487
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
488
 
          (if_exists || table_type == NULL))
 
536
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
 
537
          if_exists)
489
538
      {
490
539
        error= 0;
491
 
        thd->clear_error();
 
540
        session->clear_error();
492
541
      }
493
542
      if (error == HA_ERR_ROW_IS_REFERENCED)
494
543
      {
498
547
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
499
548
      {
500
549
        int new_error;
 
550
 
 
551
        /* for some weird-ass reason, we ignore the return code here
 
552
           and things work. */
 
553
        delete_table_proto_file(path);
 
554
 
501
555
        /* Delete the table definition file */
502
 
        my_stpcpy(end,reg_ext);
 
556
        strcpy(end,reg_ext);
503
557
        if (!(new_error=my_delete(path,MYF(MY_WME))))
504
558
        {
505
559
          some_tables_deleted=1;
520
574
    on the table name.
521
575
  */
522
576
  pthread_mutex_unlock(&LOCK_open);
523
 
  thd->thread_specific_used|= tmp_table_deleted;
 
577
  session->thread_specific_used|= tmp_table_deleted;
524
578
  error= 0;
525
579
  if (wrong_tables.length())
526
580
  {
538
592
  {
539
593
    if (!dont_log_query)
540
594
    {
541
 
      if (!thd->current_stmt_binlog_row_based ||
542
 
          (non_temp_tables_count > 0 && !tmp_table_deleted))
 
595
      if ((non_temp_tables_count > 0 && !tmp_table_deleted))
543
596
      {
544
597
        /*
545
598
          In this case, we are either using statement-based
548
601
          tables).  In this case, we can write the original query into
549
602
          the binary log.
550
603
         */
551
 
        write_bin_log(thd, !error, thd->query, thd->query_length);
 
604
        write_bin_log(session, !error, session->query, session->query_length);
552
605
      }
553
 
      else if (thd->current_stmt_binlog_row_based &&
554
 
               non_temp_tables_count > 0 &&
 
606
      else if (non_temp_tables_count > 0 &&
555
607
               tmp_table_deleted)
556
608
      {
557
609
        /*
568
620
        */
569
621
        built_query.chop();                  // Chop of the last comma
570
622
        built_query.append(" /* generated by server */");
571
 
        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
 
623
        write_bin_log(session, !error, built_query.ptr(), built_query.length());
572
624
      }
573
625
      /*
574
626
        The remaining cases are:
582
634
  }
583
635
  pthread_mutex_lock(&LOCK_open);
584
636
err_with_placeholders:
585
 
  unlock_table_names(thd, tables, (TableList*) 0);
 
637
  unlock_table_names(session, tables, (TableList*) 0);
586
638
  pthread_mutex_unlock(&LOCK_open);
587
 
  thd->no_warnings_for_error= 0;
 
639
  session->no_warnings_for_error= 0;
588
640
  return(error);
589
641
}
590
642
 
604
656
    != 0        Error
605
657
*/
606
658
 
607
 
bool quick_rm_table(handlerton *base,const char *db,
 
659
bool quick_rm_table(handlerton *,const char *db,
608
660
                    const char *table_name, uint32_t flags)
609
661
{
610
662
  char path[FN_REFLEN];
614
666
                                         db, table_name, reg_ext, flags);
615
667
  if (my_delete(path,MYF(0)))
616
668
    error= 1; /* purecov: inspected */
 
669
 
617
670
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
618
 
  return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
 
671
 
 
672
  error|= delete_table_proto_file(path);
 
673
 
 
674
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
619
675
              error);
620
676
}
621
677
 
635
691
static int sort_keys(KEY *a, KEY *b)
636
692
{
637
693
  ulong a_flags= a->flags, b_flags= b->flags;
638
 
  
 
694
 
639
695
  if (a_flags & HA_NOSAME)
640
696
  {
641
697
    if (!(b_flags & HA_NOSAME))
645
701
      /* Sort NOT NULL keys before other keys */
646
702
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
647
703
    }
648
 
    if (a->name == primary_key_name)
 
704
    if (is_primary_key(a))
649
705
      return -1;
650
 
    if (b->name == primary_key_name)
 
706
    if (is_primary_key(b))
651
707
      return 1;
652
708
    /* Sort keys don't containing partial segments before others */
653
709
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
691
747
  TYPELIB tmp= *typelib;
692
748
  const char **cur_value= typelib->type_names;
693
749
  unsigned int *cur_length= typelib->type_lengths;
694
 
  *dup_val_count= 0;  
695
 
  
 
750
  *dup_val_count= 0;
 
751
 
696
752
  for ( ; tmp.count > 1; cur_value++, cur_length++)
697
753
  {
698
754
    tmp.type_names++;
762
818
   1    Error
763
819
*/
764
820
 
765
 
int prepare_create_field(Create_field *sql_field, 
 
821
int prepare_create_field(Create_field *sql_field,
766
822
                         uint32_t *blob_columns,
767
823
                         int *timestamps, int *timestamps_with_niladic,
768
 
                         int64_t table_flags __attribute__((unused)))
 
824
                         int64_t )
769
825
{
770
826
  unsigned int dup_val_count;
771
827
 
783
839
    if (sql_field->charset->state & MY_CS_BINSORT)
784
840
      sql_field->pack_flag|=FIELDFLAG_BINARY;
785
841
    sql_field->length=8;                        // Unireg field length
786
 
    sql_field->unireg_check=Field::BLOB_FIELD;
787
842
    (*blob_columns)++;
788
843
    break;
789
844
  case DRIZZLE_TYPE_VARCHAR:
796
851
      FIELDFLAG_INTERVAL;
797
852
    if (sql_field->charset->state & MY_CS_BINSORT)
798
853
      sql_field->pack_flag|=FIELDFLAG_BINARY;
799
 
    sql_field->unireg_check=Field::INTERVAL_FIELD;
800
854
    if (check_duplicates_in_interval("ENUM",sql_field->field_name,
801
855
                                 sql_field->interval,
802
856
                                     sql_field->charset, &dup_val_count))
803
857
      return(1);
804
858
    break;
805
 
  case DRIZZLE_TYPE_NEWDATE:  // Rest of string types
 
859
  case DRIZZLE_TYPE_DATE:  // Rest of string types
806
860
  case DRIZZLE_TYPE_TIME:
807
861
  case DRIZZLE_TYPE_DATETIME:
808
862
  case DRIZZLE_TYPE_NULL:
840
894
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
841
895
    break;
842
896
  }
843
 
  if (!(sql_field->flags & NOT_NULL_FLAG))
 
897
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
 
898
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
844
899
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
845
900
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
846
901
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
852
907
 
853
908
  SYNOPSIS
854
909
    mysql_prepare_create_table()
855
 
      thd                       Thread object.
 
910
      session                       Thread object.
856
911
      create_info               Create information (like MAX_ROWS).
857
912
      alter_info                List of columns and indexes to create
858
913
      tmp_table                 If a temporary table is to be created.
874
929
*/
875
930
 
876
931
static int
877
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
932
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
878
933
                           Alter_info *alter_info,
879
934
                           bool tmp_table,
880
935
                               uint32_t *db_options,
922
977
 
923
978
    save_cs= sql_field->charset;
924
979
    if ((sql_field->flags & BINCMP_FLAG) &&
925
 
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
926
 
                                                    MY_CS_BINSORT,MYF(0))))
 
980
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, MY_CS_BINSORT)))
927
981
    {
928
982
      char tmp[64];
929
 
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
930
 
              STRING_WITH_LEN("_bin"));
 
983
      char *tmp_pos= tmp;
 
984
      strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
 
985
      tmp_pos+= strlen(tmp);
 
986
      strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
931
987
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
932
988
      return(true);
933
989
    }
936
992
      Convert the default value from client character
937
993
      set into the column character set if necessary.
938
994
    */
939
 
    if (sql_field->def && 
 
995
    if (sql_field->def &&
940
996
        save_cs != sql_field->def->collation.collation &&
941
997
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
942
998
    {
978
1034
          occupied memory at the same time when we free this
979
1035
          sql_field -- at the end of execution.
980
1036
        */
981
 
        interval= sql_field->interval= typelib(thd->mem_root,
 
1037
        interval= sql_field->interval= typelib(session->mem_root,
982
1038
                                               sql_field->interval_list);
983
1039
        List_iterator<String> int_it(sql_field->interval_list);
984
1040
        String conv, *tmp;
985
1041
        char comma_buf[4];
986
1042
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
987
 
                                          (unsigned char*) comma_buf + 
 
1043
                                          (unsigned char*) comma_buf +
988
1044
                                          sizeof(comma_buf));
989
1045
        assert(comma_length > 0);
990
1046
        for (uint32_t i= 0; (tmp= int_it++); i++)
995
1051
          {
996
1052
            uint32_t cnv_errs;
997
1053
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
998
 
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
 
1054
            interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
999
1055
                                                  conv.length());
1000
1056
            interval->type_lengths[i]= conv.length();
1001
1057
          }
1025
1081
            }
1026
1082
 
1027
1083
            /* else, the defaults yield the correct length for NULLs. */
1028
 
          } 
 
1084
          }
1029
1085
          else /* not NULL */
1030
1086
          {
1031
1087
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
1043
1099
    }
1044
1100
 
1045
1101
    sql_field->create_length_to_internal_length();
1046
 
    if (prepare_blob_field(thd, sql_field))
 
1102
    if (prepare_blob_field(session, sql_field))
1047
1103
      return(true);
1048
1104
 
1049
1105
    if (!(sql_field->flags & NOT_NULL_FLAG))
1085
1141
          sql_field->decimals=          dup_field->decimals;
1086
1142
          sql_field->create_length_to_internal_length();
1087
1143
          sql_field->unireg_check=      dup_field->unireg_check;
1088
 
          /* 
 
1144
          /*
1089
1145
            We're making one field from two, the result field will have
1090
1146
            dup_field->flags as flags. If we've incremented null_fields
1091
1147
            because of sql_field->flags, decrement it back.
1094
1150
            null_fields--;
1095
1151
          sql_field->flags=             dup_field->flags;
1096
1152
          sql_field->interval=          dup_field->interval;
 
1153
          sql_field->vcol_info=         dup_field->vcol_info;
 
1154
          sql_field->is_stored=      dup_field->is_stored;
1097
1155
          it2.remove();                 // Remove first (create) definition
1098
1156
          select_field_pos--;
1099
1157
          break;
1116
1174
  {
1117
1175
    assert(sql_field->charset != 0);
1118
1176
 
1119
 
    if (prepare_create_field(sql_field, &blob_columns, 
 
1177
    if (prepare_create_field(sql_field, &blob_columns,
1120
1178
                             &timestamps, &timestamps_with_niladic,
1121
1179
                             file->ha_table_flags()))
1122
1180
      return(true);
1125
1183
    sql_field->offset= record_offset;
1126
1184
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1127
1185
      auto_increment++;
1128
 
    record_offset+= sql_field->pack_length;
 
1186
    /*
 
1187
          For now skip fields that are not physically stored in the database
 
1188
          (virtual fields) and update their offset later
 
1189
          (see the next loop).
 
1190
        */
 
1191
    if (sql_field->is_stored)
 
1192
      record_offset+= sql_field->pack_length;
 
1193
  }
 
1194
  /* Update virtual fields' offset */
 
1195
  it.rewind();
 
1196
  while ((sql_field=it++))
 
1197
  {
 
1198
    if (not sql_field->is_stored)
 
1199
    {
 
1200
      sql_field->offset= record_offset;
 
1201
      record_offset+= sql_field->pack_length;
 
1202
    }
1129
1203
  }
1130
1204
  if (timestamps_with_niladic > 1)
1131
1205
  {
1172
1246
    if (key->type == Key::FOREIGN_KEY)
1173
1247
    {
1174
1248
      fk_key_count++;
 
1249
      if (((Foreign_key *)key)->validate(alter_info->create_list))
 
1250
        return true;
1175
1251
      Foreign_key *fk_key= (Foreign_key*) key;
1176
1252
      if (fk_key->ref_columns.elements &&
1177
1253
          fk_key->ref_columns.elements != fk_key->columns.elements)
1228
1304
    else
1229
1305
      (*key_count)--;
1230
1306
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
1231
 
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
 
1307
        is_primary_key_name(key->name.str))
1232
1308
    {
1233
1309
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1234
1310
      return(true);
1361
1437
            return(true);
1362
1438
          }
1363
1439
        }
 
1440
        if (not sql_field->is_stored)
 
1441
        {
 
1442
          /* Key fields must always be physically stored. */
 
1443
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
 
1444
          return(true);
 
1445
        }
 
1446
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
 
1447
        {
 
1448
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
 
1449
          return(true);
 
1450
        }
1364
1451
        if (!(sql_field->flags & NOT_NULL_FLAG))
1365
1452
        {
1366
1453
          if (key->type == Key::PRIMARY)
1406
1493
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
1407
1494
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1408
1495
                       length);
1409
 
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1496
              push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1410
1497
                           ER_TOO_LONG_KEY, warn_buff);
1411
1498
              /* Align key length to multibyte char boundary */
1412
1499
              length-= length % sql_field->charset->mbmaxlen;
1445
1532
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1446
1533
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1447
1534
                   length);
1448
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1535
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1449
1536
                       ER_TOO_LONG_KEY, warn_buff);
1450
1537
          /* Align key length to multibyte char boundary */
1451
1538
          length-= length % sql_field->charset->mbmaxlen;
1487
1574
                       MYF(0));
1488
1575
            return(true);
1489
1576
          }
1490
 
          key_name=primary_key_name;
 
1577
          static const char pkey_name[]= "PRIMARY";
 
1578
          key_name=pkey_name;
1491
1579
          primary_key=1;
1492
1580
        }
1493
1581
        else if (!(key_name= key->name.str))
1538
1626
  {
1539
1627
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1540
1628
 
1541
 
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
 
1629
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1542
1630
        !sql_field->def &&
1543
1631
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1544
1632
        (sql_field->flags & NOT_NULL_FLAG) &&
1566
1654
  return(false);
1567
1655
}
1568
1656
 
1569
 
 
1570
 
/*
1571
 
  Set table default charset, if not set
1572
 
 
1573
 
  SYNOPSIS
1574
 
    set_table_default_charset()
1575
 
    create_info        Table create information
1576
 
 
1577
 
  DESCRIPTION
1578
 
    If the table character set was not given explicitely,
1579
 
    let's fetch the database default character set and
1580
 
    apply it to the table.
1581
 
*/
1582
 
 
1583
 
static void set_table_default_charset(THD *thd,
1584
 
                                      HA_CREATE_INFO *create_info, char *db)
1585
 
{
1586
 
  /*
1587
 
    If the table character set was not given explicitly,
1588
 
    let's fetch the database default character set and
1589
 
    apply it to the table.
1590
 
  */
1591
 
  if (!create_info->default_table_charset)
1592
 
  {
1593
 
    HA_CREATE_INFO db_info;
1594
 
 
1595
 
    load_db_opt_by_name(thd, db, &db_info);
1596
 
 
1597
 
    create_info->default_table_charset= db_info.default_table_charset;
1598
 
  }
1599
 
}
1600
 
 
1601
 
 
1602
1657
/*
1603
1658
  Extend long VARCHAR fields to blob & prepare field if it's a blob
1604
1659
 
1612
1667
        In this case the error is given
1613
1668
*/
1614
1669
 
1615
 
static bool prepare_blob_field(THD *thd __attribute__((unused)),
 
1670
static bool prepare_blob_field(Session *,
1616
1671
                               Create_field *sql_field)
1617
1672
{
1618
1673
 
1623
1678
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1624
1679
    return(1);
1625
1680
  }
1626
 
    
 
1681
 
1627
1682
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1628
1683
  {
1629
1684
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1639
1694
 
1640
1695
 
1641
1696
/*
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
1697
  Create a table
1680
1698
 
1681
1699
  SYNOPSIS
1682
1700
    mysql_create_table_no_lock()
1683
 
    thd                 Thread object
 
1701
    session                     Thread object
1684
1702
    db                  Database
1685
1703
    table_name          Table name
1686
1704
    create_info         Create information (like MAX_ROWS)
1688
1706
    keys                List of keys to create
1689
1707
    internal_tmp_table  Set to 1 if this is an internal temporary table
1690
1708
                        (From ALTER Table)
1691
 
    select_field_count  
 
1709
    select_field_count
1692
1710
 
1693
1711
  DESCRIPTION
1694
1712
    If one creates a temporary table, this is automatically opened
1708
1726
    true  error
1709
1727
*/
1710
1728
 
1711
 
bool mysql_create_table_no_lock(THD *thd,
 
1729
bool mysql_create_table_no_lock(Session *session,
1712
1730
                                const char *db, const char *table_name,
1713
1731
                                HA_CREATE_INFO *create_info,
1714
1732
                                Alter_info *alter_info,
1715
1733
                                bool internal_tmp_table,
1716
 
                                uint32_t select_field_count)
 
1734
                                uint32_t select_field_count,
 
1735
                                bool lock_open_lock)
1717
1736
{
1718
1737
  char          path[FN_REFLEN];
1719
1738
  uint32_t          path_length;
1729
1748
               MYF(0));
1730
1749
    return(true);
1731
1750
  }
1732
 
  if (check_engine(thd, table_name, create_info))
 
1751
  if (check_engine(session, table_name, create_info))
1733
1752
    return(true);
1734
1753
  db_options= create_info->table_options;
1735
1754
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1736
1755
    db_options|=HA_OPTION_PACK_RECORD;
1737
1756
  alias= table_case_name(create_info, table_name);
1738
 
  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
 
1757
  if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1739
1758
                              create_info->db_type)))
1740
1759
  {
1741
1760
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1742
1761
    return(true);
1743
1762
  }
1744
1763
 
1745
 
  set_table_default_charset(thd, create_info, (char*) db);
 
1764
  set_table_default_charset(session, create_info, (char*) db);
1746
1765
 
1747
 
  if (mysql_prepare_create_table(thd, create_info, alter_info,
 
1766
  if (mysql_prepare_create_table(session, create_info, alter_info,
1748
1767
                                 internal_tmp_table,
1749
1768
                                 &db_options, file,
1750
1769
                          &key_info_buffer, &key_count,
1754
1773
      /* Check if table exists */
1755
1774
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1756
1775
  {
1757
 
    path_length= build_tmptable_filename(thd, path, sizeof(path));
 
1776
    path_length= build_tmptable_filename(session, path, sizeof(path));
1758
1777
    create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1759
1778
  }
1760
 
  else  
 
1779
  else
1761
1780
  {
1762
1781
 #ifdef FN_DEVCHAR
1763
1782
    /* check if the table name contains FN_DEVCHAR when defined */
1773
1792
 
1774
1793
  /* Check if table already exists */
1775
1794
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1776
 
      find_temporary_table(thd, db, table_name))
 
1795
      find_temporary_table(session, db, table_name))
1777
1796
  {
1778
1797
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1779
1798
    {
1780
1799
      create_info->table_existed= 1;            // Mark that table existed
1781
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1800
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1782
1801
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1783
1802
                          alias);
1784
1803
      error= 0;
1788
1807
    goto err;
1789
1808
  }
1790
1809
 
1791
 
  pthread_mutex_lock(&LOCK_open);
 
1810
  if (lock_open_lock)
 
1811
    pthread_mutex_lock(&LOCK_open);
1792
1812
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1793
1813
  {
1794
1814
    if (!access(path,F_OK))
1826
1846
  {
1827
1847
    bool create_if_not_exists =
1828
1848
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1829
 
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
 
1849
    int retcode = ha_table_exists_in_engine(session, db, table_name);
1830
1850
    switch (retcode)
1831
1851
    {
1832
1852
      case HA_ERR_NO_SUCH_TABLE:
1845
1865
    }
1846
1866
  }
1847
1867
 
1848
 
  thd_proc_info(thd, "creating table");
 
1868
  session->set_proc_info("creating table");
1849
1869
  create_info->table_existed= 0;                // Mark that table is created
1850
1870
 
1851
1871
#ifdef HAVE_READLINK
1864
1884
#endif /* HAVE_READLINK */
1865
1885
  {
1866
1886
    if (create_info->data_file_name)
1867
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1887
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1868
1888
                   "DATA DIRECTORY option ignored");
1869
1889
    if (create_info->index_file_name)
1870
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1890
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1871
1891
                   "INDEX DIRECTORY option ignored");
1872
1892
    create_info->data_file_name= create_info->index_file_name= 0;
1873
1893
  }
1874
1894
  create_info->table_options=db_options;
1875
1895
 
1876
1896
  path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1877
 
  if (rea_create_table(thd, path, db, table_name,
 
1897
  if (rea_create_table(session, path, db, table_name,
1878
1898
                       create_info, alter_info->create_list,
1879
 
                       key_count, key_info_buffer, file))
 
1899
                       key_count, key_info_buffer, file, false))
1880
1900
    goto unlock_and_end;
1881
1901
 
1882
1902
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1883
1903
  {
1884
1904
    /* Open table and put in temporary table list */
1885
 
    if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
 
1905
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1886
1906
    {
1887
 
      (void) rm_temporary_table(create_info->db_type, path, false);
 
1907
      (void) rm_temporary_table(create_info->db_type, path);
1888
1908
      goto unlock_and_end;
1889
1909
    }
1890
 
    thd->thread_specific_used= true;
 
1910
    session->thread_specific_used= true;
1891
1911
  }
1892
1912
 
1893
1913
  /*
1898
1918
    Otherwise, the statement shall be binlogged.
1899
1919
   */
1900
1920
  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);
 
1921
      ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
 
1922
    write_bin_log(session, true, session->query, session->query_length);
1905
1923
  error= false;
1906
1924
unlock_and_end:
1907
 
  pthread_mutex_unlock(&LOCK_open);
 
1925
  if (lock_open_lock)
 
1926
    pthread_mutex_unlock(&LOCK_open);
1908
1927
 
1909
1928
err:
1910
 
  thd_proc_info(thd, "After create");
 
1929
  session->set_proc_info("After create");
1911
1930
  delete file;
1912
1931
  return(error);
1913
1932
 
1914
1933
warn:
1915
1934
  error= false;
1916
 
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1935
  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1917
1936
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1918
1937
                      alias);
1919
1938
  create_info->table_existed= 1;                // Mark that table existed
1925
1944
  Database locking aware wrapper for mysql_create_table_no_lock(),
1926
1945
*/
1927
1946
 
1928
 
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
 
1947
bool mysql_create_table(Session *session, const char *db, const char *table_name,
1929
1948
                        HA_CREATE_INFO *create_info,
1930
1949
                        Alter_info *alter_info,
1931
1950
                        bool internal_tmp_table,
1936
1955
 
1937
1956
  /* Wait for any database locks */
1938
1957
  pthread_mutex_lock(&LOCK_lock_db);
1939
 
  while (!thd->killed &&
 
1958
  while (!session->killed &&
1940
1959
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
1941
1960
  {
1942
 
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1961
    wait_for_condition(session, &LOCK_lock_db, &COND_refresh);
1943
1962
    pthread_mutex_lock(&LOCK_lock_db);
1944
1963
  }
1945
1964
 
1946
 
  if (thd->killed)
 
1965
  if (session->killed)
1947
1966
  {
1948
1967
    pthread_mutex_unlock(&LOCK_lock_db);
1949
1968
    return(true);
1953
1972
 
1954
1973
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1955
1974
  {
1956
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
1975
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
1957
1976
    {
1958
1977
      result= true;
1959
1978
      goto unlock;
1962
1981
    {
1963
1982
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1964
1983
      {
1965
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1984
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1966
1985
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1967
1986
                            table_name);
1968
1987
        create_info->table_existed= 1;
1977
1996
    }
1978
1997
  }
1979
1998
 
1980
 
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
 
1999
  result= mysql_create_table_no_lock(session, db, table_name, create_info,
1981
2000
                                     alter_info,
1982
2001
                                     internal_tmp_table,
1983
 
                                     select_field_count);
 
2002
                                     select_field_count, true);
1984
2003
 
1985
2004
unlock:
1986
2005
  if (name_lock)
1987
2006
  {
1988
2007
    pthread_mutex_lock(&LOCK_open);
1989
 
    unlink_open_table(thd, name_lock, false);
 
2008
    unlink_open_table(session, name_lock, false);
1990
2009
    pthread_mutex_unlock(&LOCK_open);
1991
2010
  }
1992
2011
  pthread_mutex_lock(&LOCK_lock_db);
2017
2036
  char buff[MAX_FIELD_NAME],*buff_end;
2018
2037
 
2019
2038
  if (!check_if_keyname_exists(field_name,start,end) &&
2020
 
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
 
2039
      !is_primary_key_name(field_name))
2021
2040
    return (char*) field_name;                  // Use fieldname
2022
 
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
 
2041
 
 
2042
  buff_end= strncpy(buff, field_name, sizeof(buff)-4);
 
2043
  buff_end+= strlen(buff);
2023
2044
 
2024
2045
  /*
2025
2046
    Only 3 chars + '\0' left, so need to limit to 2 digit
2067
2088
                   const char *old_name, const char *new_db,
2068
2089
                   const char *new_name, uint32_t flags)
2069
2090
{
2070
 
  THD *thd= current_thd;
 
2091
  Session *session= current_session;
2071
2092
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2072
2093
  char *from_base= from, *to_base= to;
2073
2094
  char tmp_name[NAME_LEN+1];
2075
2096
  int error=0;
2076
2097
 
2077
2098
  file= (base == NULL ? 0 :
2078
 
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
 
2099
         get_new_handler((TABLE_SHARE*) 0, session->mem_root, base));
2079
2100
 
2080
2101
  build_table_filename(from, sizeof(from), old_db, old_name, "",
2081
2102
                       flags & FN_FROM_IS_TMP);
2090
2111
  if (lower_case_table_names == 2 && file &&
2091
2112
      !(file->ha_table_flags() & HA_FILE_BASED))
2092
2113
  {
2093
 
    my_stpcpy(tmp_name, old_name);
 
2114
    strcpy(tmp_name, old_name);
2094
2115
    my_casedn_str(files_charset_info, tmp_name);
2095
2116
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2096
2117
                         flags & FN_FROM_IS_TMP);
2097
2118
    from_base= lc_from;
2098
2119
 
2099
 
    my_stpcpy(tmp_name, new_name);
 
2120
    strcpy(tmp_name, new_name);
2100
2121
    my_casedn_str(files_charset_info, tmp_name);
2101
2122
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2102
2123
                         flags & FN_TO_IS_TMP);
2111
2132
      if (file)
2112
2133
        file->ha_rename_table(to_base, from_base);
2113
2134
    }
 
2135
 
 
2136
    if(!(flags & NO_FRM_RENAME)
 
2137
       && rename_table_proto_file(from_base, to_base))
 
2138
    {
 
2139
      error= errno;
 
2140
      rename_file_ext(to, from, reg_ext);
 
2141
      if (file)
 
2142
        file->ha_rename_table(to_base, from_base);
 
2143
    }
2114
2144
  }
2115
2145
  delete file;
2116
2146
  if (error == HA_ERR_WRONG_COMMAND)
2126
2156
 
2127
2157
  SYNOPSIS
2128
2158
    wait_while_table_is_used()
2129
 
    thd                 Thread handler
 
2159
    session                     Thread handler
2130
2160
    table               Table to remove from cache
2131
2161
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2132
2162
                        HA_EXTRA_FORCE_REOPEN if table is not be used
2140
2170
    Win32 clients must also have a WRITE LOCK on the table !
2141
2171
*/
2142
2172
 
2143
 
void wait_while_table_is_used(THD *thd, Table *table,
 
2173
void wait_while_table_is_used(Session *session, Table *table,
2144
2174
                              enum ha_extra_function function)
2145
2175
{
2146
2176
 
2148
2178
 
2149
2179
  table->file->extra(function);
2150
2180
  /* Mark all tables that are in use as 'old' */
2151
 
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
 
2181
  mysql_lock_abort(session, table, true);       /* end threads waiting on lock */
2152
2182
 
2153
2183
  /* Wait until all there are no other threads that has this table open */
2154
 
  remove_table_from_cache(thd, table->s->db.str,
 
2184
  remove_table_from_cache(session, table->s->db.str,
2155
2185
                          table->s->table_name.str,
2156
2186
                          RTFC_WAIT_OTHER_THREAD_FLAG);
2157
2187
  return;
2162
2192
 
2163
2193
  SYNOPSIS
2164
2194
    close_cached_table()
2165
 
    thd                 Thread handler
 
2195
    session                     Thread handler
2166
2196
    table               Table to remove from cache
2167
2197
 
2168
2198
  NOTES
2174
2204
    Win32 clients must also have a WRITE LOCK on the table !
2175
2205
*/
2176
2206
 
2177
 
void close_cached_table(THD *thd, Table *table)
 
2207
void close_cached_table(Session *session, Table *table)
2178
2208
{
2179
2209
 
2180
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
2210
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2181
2211
  /* Close lock if this is not got with LOCK TABLES */
2182
 
  if (thd->lock)
 
2212
  if (session->lock)
2183
2213
  {
2184
 
    mysql_unlock_tables(thd, thd->lock);
2185
 
    thd->lock=0;                        // Start locked threads
 
2214
    mysql_unlock_tables(session, session->lock);
 
2215
    session->lock=0;                    // Start locked threads
2186
2216
  }
2187
2217
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
2188
 
  unlink_open_table(thd, table, true);
 
2218
  unlink_open_table(session, table, true);
2189
2219
 
2190
2220
  /* When lock on LOCK_open is freed other threads can continue */
2191
2221
  broadcast_refresh();
2192
2222
  return;
2193
2223
}
2194
2224
 
2195
 
static int send_check_errmsg(THD *thd, TableList* table,
 
2225
static int send_check_errmsg(Session *session, TableList* table,
2196
2226
                             const char* operator_name, const char* errmsg)
2197
2227
 
2198
2228
{
2199
 
  Protocol *protocol= thd->protocol;
 
2229
  Protocol *protocol= session->protocol;
2200
2230
  protocol->prepare_for_resend();
2201
2231
  protocol->store(table->alias, system_charset_info);
2202
2232
  protocol->store((char*) operator_name, system_charset_info);
2203
2233
  protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2204
2234
  protocol->store(errmsg, system_charset_info);
2205
 
  thd->clear_error();
 
2235
  session->clear_error();
2206
2236
  if (protocol->write())
2207
2237
    return -1;
2208
2238
  return 1;
2209
2239
}
2210
2240
 
2211
2241
 
2212
 
static int prepare_for_repair(THD *thd, TableList *table_list,
 
2242
static int prepare_for_repair(Session *session, TableList *table_list,
2213
2243
                              HA_CHECK_OPT *check_opt)
2214
2244
{
2215
2245
  int error= 0;
2219
2249
  const char **ext;
2220
2250
  struct stat stat_info;
2221
2251
 
2222
 
  if (!(check_opt->sql_flags & TT_USEFRM))
 
2252
  if (!(check_opt->use_frm))
2223
2253
    return(0);
2224
2254
 
2225
2255
  if (!(table= table_list->table))              /* if open_ltable failed */
2227
2257
    char key[MAX_DBKEY_LENGTH];
2228
2258
    uint32_t key_length;
2229
2259
 
2230
 
    key_length= create_table_def_key(thd, key, table_list, 0);
 
2260
    key_length= create_table_def_key(session, key, table_list, 0);
2231
2261
    pthread_mutex_lock(&LOCK_open);
2232
 
    if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
 
2262
    if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2233
2263
                                  &error))))
2234
2264
    {
2235
2265
      pthread_mutex_unlock(&LOCK_open);
2236
2266
      return(0);                                // Can't open frm file
2237
2267
    }
2238
2268
 
2239
 
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
 
2269
    if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2240
2270
    {
2241
2271
      release_table_share(share, RELEASE_NORMAL);
2242
2272
      pthread_mutex_unlock(&LOCK_open);
2251
2281
  */
2252
2282
  if (table->s->tmp_table)
2253
2283
  {
2254
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2284
    error= send_check_errmsg(session, table_list, "repair",
2255
2285
                             "Cannot repair temporary table from .frm file");
2256
2286
    goto end;
2257
2287
  }
2270
2300
    Check if this is a table type that stores index and data separately,
2271
2301
    like ISAM or MyISAM. We assume fixed order of engine file name
2272
2302
    extentions array. First element of engine file name extentions array
2273
 
    is meta/index file extention. Second element - data file extention. 
 
2303
    is meta/index file extention. Second element - data file extention.
2274
2304
  */
2275
2305
  ext= table->file->bas_ext();
2276
2306
  if (!ext[0] || !ext[1])
2277
2307
    goto end;                                   // No data file
2278
2308
 
2279
2309
  // Name of data file
2280
 
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
 
2310
  sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2281
2311
  if (stat(from, &stat_info))
2282
2312
    goto end;                           // Can't use USE_FRM flag
2283
2313
 
2284
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2285
 
           from, current_pid, thd->thread_id);
 
2314
  snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
 
2315
           from, (unsigned long)current_pid, session->thread_id);
2286
2316
 
2287
2317
  /* If we could open the table, close it */
2288
2318
  if (table_list->table)
2289
2319
  {
2290
2320
    pthread_mutex_lock(&LOCK_open);
2291
 
    close_cached_table(thd, table);
 
2321
    close_cached_table(session, table);
2292
2322
    pthread_mutex_unlock(&LOCK_open);
2293
2323
  }
2294
 
  if (lock_and_wait_for_table_name(thd,table_list))
 
2324
  if (lock_and_wait_for_table_name(session,table_list))
2295
2325
  {
2296
2326
    error= -1;
2297
2327
    goto end;
2299
2329
  if (my_rename(from, tmp, MYF(MY_WME)))
2300
2330
  {
2301
2331
    pthread_mutex_lock(&LOCK_open);
2302
 
    unlock_table_name(thd, table_list);
 
2332
    unlock_table_name(session, table_list);
2303
2333
    pthread_mutex_unlock(&LOCK_open);
2304
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2334
    error= send_check_errmsg(session, table_list, "repair",
2305
2335
                             "Failed renaming data file");
2306
2336
    goto end;
2307
2337
  }
2308
 
  if (mysql_truncate(thd, table_list, 1))
 
2338
  if (mysql_truncate(session, table_list, 1))
2309
2339
  {
2310
2340
    pthread_mutex_lock(&LOCK_open);
2311
 
    unlock_table_name(thd, table_list);
 
2341
    unlock_table_name(session, table_list);
2312
2342
    pthread_mutex_unlock(&LOCK_open);
2313
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2343
    error= send_check_errmsg(session, table_list, "repair",
2314
2344
                             "Failed generating table from .frm file");
2315
2345
    goto end;
2316
2346
  }
2317
2347
  if (my_rename(tmp, from, MYF(MY_WME)))
2318
2348
  {
2319
2349
    pthread_mutex_lock(&LOCK_open);
2320
 
    unlock_table_name(thd, table_list);
 
2350
    unlock_table_name(session, table_list);
2321
2351
    pthread_mutex_unlock(&LOCK_open);
2322
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2352
    error= send_check_errmsg(session, table_list, "repair",
2323
2353
                             "Failed restoring .MYD file");
2324
2354
    goto end;
2325
2355
  }
2329
2359
    to finish the repair in the handler later on.
2330
2360
  */
2331
2361
  pthread_mutex_lock(&LOCK_open);
2332
 
  if (reopen_name_locked_table(thd, table_list, true))
 
2362
  if (reopen_name_locked_table(session, table_list, true))
2333
2363
  {
2334
 
    unlock_table_name(thd, table_list);
 
2364
    unlock_table_name(session, table_list);
2335
2365
    pthread_mutex_unlock(&LOCK_open);
2336
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2366
    error= send_check_errmsg(session, table_list, "repair",
2337
2367
                             "Failed to open partially repaired table");
2338
2368
    goto end;
2339
2369
  }
2343
2373
  if (table == &tmp_table)
2344
2374
  {
2345
2375
    pthread_mutex_lock(&LOCK_open);
2346
 
    closefrm(table, 1);                         // Free allocated memory
 
2376
    table->closefrm(true);                              // Free allocated memory
2347
2377
    pthread_mutex_unlock(&LOCK_open);
2348
2378
  }
2349
2379
  return(error);
2354
2384
/*
2355
2385
  RETURN VALUES
2356
2386
    false Message sent to net (admin operation went ok)
2357
 
    true  Message should be sent by caller 
 
2387
    true  Message should be sent by caller
2358
2388
          (admin operation or network communication failed)
2359
2389
*/
2360
 
static bool mysql_admin_table(THD* thd, TableList* tables,
 
2390
static bool mysql_admin_table(Session* session, TableList* tables,
2361
2391
                              HA_CHECK_OPT* check_opt,
2362
2392
                              const char *operator_name,
2363
2393
                              thr_lock_type lock_type,
2364
2394
                              bool open_for_modify,
2365
2395
                              bool no_warnings_for_error,
2366
2396
                              uint32_t extra_open_options,
2367
 
                              int (*prepare_func)(THD *, TableList *,
 
2397
                              int (*prepare_func)(Session *, TableList *,
2368
2398
                                                  HA_CHECK_OPT *),
2369
 
                              int (handler::*operator_func)(THD *,
 
2399
                              int (handler::*operator_func)(Session *,
2370
2400
                                                            HA_CHECK_OPT *))
2371
2401
{
2372
2402
  TableList *table;
2373
 
  SELECT_LEX *select= &thd->lex->select_lex;
 
2403
  Select_Lex *select= &session->lex->select_lex;
2374
2404
  List<Item> field_list;
2375
2405
  Item *item;
2376
 
  Protocol *protocol= thd->protocol;
2377
 
  LEX *lex= thd->lex;
 
2406
  Protocol *protocol= session->protocol;
 
2407
  LEX *lex= session->lex;
2378
2408
  int result_code= 0;
2379
2409
  const CHARSET_INFO * const cs= system_charset_info;
2380
2410
 
2381
 
  if (end_active_trans(thd))
 
2411
  if (end_active_trans(session))
2382
2412
    return(1);
2383
2413
  field_list.push_back(item = new Item_empty_string("Table",
2384
2414
                                                    NAME_CHAR_LEN * 2,
2394
2424
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2395
2425
    return(true);
2396
2426
 
2397
 
  mysql_ha_rm_tables(thd, tables, false);
 
2427
  mysql_ha_rm_tables(session, tables, false);
2398
2428
 
2399
2429
  for (table= tables; table; table= table->next_local)
2400
2430
  {
2402
2432
    char* db = table->db;
2403
2433
    bool fatal_error=0;
2404
2434
 
2405
 
    strxmov(table_name, db, ".", table->table_name, NULL);
2406
 
    thd->open_options|= extra_open_options;
 
2435
    sprintf(table_name,"%s.%s",db,table->table_name);
 
2436
    session->open_options|= extra_open_options;
2407
2437
    table->lock_type= lock_type;
2408
2438
    /* open only one table from local list of command */
2409
2439
    {
2422
2452
      lex->query_tables= table;
2423
2453
      lex->query_tables_last= &table->next_global;
2424
2454
      lex->query_tables_own_last= 0;
2425
 
      thd->no_warnings_for_error= no_warnings_for_error;
 
2455
      session->no_warnings_for_error= no_warnings_for_error;
2426
2456
 
2427
 
      open_and_lock_tables(thd, table);
2428
 
      thd->no_warnings_for_error= 0;
 
2457
      open_and_lock_tables(session, table);
 
2458
      session->no_warnings_for_error= 0;
2429
2459
      table->next_global= save_next_global;
2430
2460
      table->next_local= save_next_local;
2431
 
      thd->open_options&= ~extra_open_options;
 
2461
      session->open_options&= ~extra_open_options;
2432
2462
    }
2433
2463
 
2434
2464
    if (prepare_func)
2435
2465
    {
2436
 
      switch ((*prepare_func)(thd, table, check_opt)) {
 
2466
      switch ((*prepare_func)(session, table, check_opt)) {
2437
2467
      case  1:           // error, message written to net
2438
 
        ha_autocommit_or_rollback(thd, 1);
2439
 
        end_trans(thd, ROLLBACK);
2440
 
        close_thread_tables(thd);
 
2468
        ha_autocommit_or_rollback(session, 1);
 
2469
        end_trans(session, ROLLBACK);
 
2470
        close_thread_tables(session);
2441
2471
        continue;
2442
2472
      case -1:           // error, message could be written to net
2443
2473
        /* purecov: begin inspected */
2458
2488
    */
2459
2489
    if (!table->table)
2460
2490
    {
2461
 
      if (!thd->warn_list.elements)
2462
 
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2491
      if (!session->warn_list.elements)
 
2492
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
2463
2493
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2464
2494
      goto send_result;
2465
2495
    }
2476
2506
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2477
2507
                       table_name);
2478
2508
      protocol->store(buff, length, system_charset_info);
2479
 
      ha_autocommit_or_rollback(thd, 0);
2480
 
      end_trans(thd, COMMIT);
2481
 
      close_thread_tables(thd);
 
2509
      ha_autocommit_or_rollback(session, 0);
 
2510
      end_trans(session, COMMIT);
 
2511
      close_thread_tables(session);
2482
2512
      lex->reset_query_tables_list(false);
2483
2513
      table->table=0;                           // For query cache
2484
2514
      if (protocol->write())
2491
2521
    if (lock_type == TL_WRITE && table->table->s->version)
2492
2522
    {
2493
2523
      pthread_mutex_lock(&LOCK_open);
2494
 
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
 
2524
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2495
2525
                                              "Waiting to get writelock");
2496
 
      mysql_lock_abort(thd,table->table, true);
2497
 
      remove_table_from_cache(thd, table->table->s->db.str,
 
2526
      mysql_lock_abort(session,table->table, true);
 
2527
      remove_table_from_cache(session, table->table->s->db.str,
2498
2528
                              table->table->s->table_name.str,
2499
2529
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2500
2530
                              RTFC_CHECK_KILLED_FLAG);
2501
 
      thd->exit_cond(old_message);
2502
 
      if (thd->killed)
 
2531
      session->exit_cond(old_message);
 
2532
      if (session->killed)
2503
2533
        goto err;
2504
2534
      open_for_modify= 0;
2505
2535
    }
2518
2548
      /* purecov: end */
2519
2549
    }
2520
2550
 
2521
 
    if (operator_func == &handler::ha_repair &&
2522
 
        !(check_opt->sql_flags & TT_USEFRM))
 
2551
    if (operator_func == &handler::ha_repair && !(check_opt->use_frm))
2523
2552
    {
2524
2553
      if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
2525
2554
          (table->table->file->ha_check_for_upgrade(check_opt) ==
2526
2555
           HA_ADMIN_NEEDS_ALTER))
2527
2556
      {
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);
 
2557
        ha_autocommit_or_rollback(session, 1);
 
2558
        close_thread_tables(session);
 
2559
        result_code= mysql_recreate_table(session, table);
2533
2560
        /*
2534
2561
          mysql_recreate_table() can push OK or ERROR.
2535
2562
          Clear 'OK' status. If there is an error, keep it:
2536
 
          we will store the error message in a result set row 
 
2563
          we will store the error message in a result set row
2537
2564
          and then clear.
2538
2565
        */
2539
 
        if (thd->main_da.is_ok())
2540
 
          thd->main_da.reset_diagnostics_area();
 
2566
        if (session->main_da.is_ok())
 
2567
          session->main_da.reset_diagnostics_area();
2541
2568
        goto send_result;
2542
2569
      }
2543
2570
    }
2544
2571
 
2545
 
    result_code = (table->table->file->*operator_func)(thd, check_opt);
 
2572
    result_code = (table->table->file->*operator_func)(session, check_opt);
2546
2573
 
2547
2574
send_result:
2548
2575
 
2549
2576
    lex->cleanup_after_one_table_open();
2550
 
    thd->clear_error();  // these errors shouldn't get client
 
2577
    session->clear_error();  // these errors shouldn't get client
2551
2578
    {
2552
 
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
2579
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2553
2580
      DRIZZLE_ERROR *err;
2554
2581
      while ((err= it++))
2555
2582
      {
2563
2590
        if (protocol->write())
2564
2591
          goto err;
2565
2592
      }
2566
 
      drizzle_reset_errors(thd, true);
 
2593
      drizzle_reset_errors(session, true);
2567
2594
    }
2568
2595
    protocol->prepare_for_resend();
2569
2596
    protocol->store(table_name, system_charset_info);
2582
2609
      }
2583
2610
      break;
2584
2611
 
2585
 
    case HA_ADMIN_NOT_BASE_TABLE:
2586
 
      {
2587
 
        char buf[ERRMSGSIZE+20];
2588
 
        uint32_t length= snprintf(buf, ERRMSGSIZE,
2589
 
                              ER(ER_BAD_TABLE_ERROR), table_name);
2590
 
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2591
 
        protocol->store(buf, length, system_charset_info);
2592
 
      }
2593
 
      break;
2594
 
 
2595
2612
    case HA_ADMIN_OK:
2596
2613
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
2597
2614
      protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
2635
2652
        "try with alter", so here we close the table, do an ALTER Table,
2636
2653
        reopen the table and do ha_innobase::analyze() on it.
2637
2654
      */
2638
 
      ha_autocommit_or_rollback(thd, 0);
2639
 
      close_thread_tables(thd);
 
2655
      ha_autocommit_or_rollback(session, 0);
 
2656
      close_thread_tables(session);
2640
2657
      TableList *save_next_local= table->next_local,
2641
2658
                 *save_next_global= table->next_global;
2642
2659
      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);
 
2660
      result_code= mysql_recreate_table(session, table);
2646
2661
      /*
2647
2662
        mysql_recreate_table() can push OK or ERROR.
2648
2663
        Clear 'OK' status. If there is an error, keep it:
2649
 
        we will store the error message in a result set row 
 
2664
        we will store the error message in a result set row
2650
2665
        and then clear.
2651
2666
      */
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);
 
2667
      if (session->main_da.is_ok())
 
2668
        session->main_da.reset_diagnostics_area();
 
2669
      ha_autocommit_or_rollback(session, 0);
 
2670
      close_thread_tables(session);
2656
2671
      if (!result_code) // recreation went ok
2657
2672
      {
2658
 
        if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
2659
 
            ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
 
2673
        if ((table->table= open_ltable(session, table, lock_type, 0)) &&
 
2674
            ((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2660
2675
          result_code= 0; // analyze went ok
2661
2676
      }
2662
2677
      if (result_code) // either mysql_recreate_table or analyze failed
2663
2678
      {
2664
 
        assert(thd->is_error());
2665
 
        if (thd->is_error())
 
2679
        assert(session->is_error());
 
2680
        if (session->is_error())
2666
2681
        {
2667
 
          const char *err_msg= thd->main_da.message();
2668
 
          if (!thd->vio_ok())
 
2682
          const char *err_msg= session->main_da.message();
 
2683
          if (!session->drizzleclient_vio_ok())
2669
2684
          {
2670
 
            sql_print_error(err_msg);
 
2685
            errmsg_printf(ERRMSG_LVL_ERROR, "%s", err_msg);
2671
2686
          }
2672
2687
          else
2673
2688
          {
2680
2695
            protocol->store(table_name, system_charset_info);
2681
2696
            protocol->store(operator_name, system_charset_info);
2682
2697
          }
2683
 
          thd->clear_error();
 
2698
          session->clear_error();
2684
2699
        }
2685
2700
      }
2686
2701
      result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
2688
2703
      table->next_global= save_next_global;
2689
2704
      goto send_result_message;
2690
2705
    }
2691
 
    case HA_ADMIN_WRONG_CHECKSUM:
2692
 
    {
2693
 
      protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2694
 
      protocol->store(ER(ER_VIEW_CHECKSUM), strlen(ER(ER_VIEW_CHECKSUM)),
2695
 
                      system_charset_info);
2696
 
      break;
2697
 
    }
2698
 
 
2699
2706
    case HA_ADMIN_NEEDS_UPGRADE:
2700
2707
    case HA_ADMIN_NEEDS_ALTER:
2701
2708
    {
2732
2739
        else
2733
2740
        {
2734
2741
          pthread_mutex_lock(&LOCK_open);
2735
 
          remove_table_from_cache(thd, table->table->s->db.str,
 
2742
          remove_table_from_cache(session, table->table->s->db.str,
2736
2743
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
2737
2744
          pthread_mutex_unlock(&LOCK_open);
2738
2745
        }
2739
2746
      }
2740
2747
    }
2741
 
    ha_autocommit_or_rollback(thd, 0);
2742
 
    end_trans(thd, COMMIT);
2743
 
    close_thread_tables(thd);
 
2748
    ha_autocommit_or_rollback(session, 0);
 
2749
    end_trans(session, COMMIT);
 
2750
    close_thread_tables(session);
2744
2751
    table->table=0;                             // For query cache
2745
2752
    if (protocol->write())
2746
2753
      goto err;
2747
2754
  }
2748
2755
 
2749
 
  my_eof(thd);
 
2756
  session->my_eof();
2750
2757
  return(false);
2751
2758
 
2752
2759
err:
2753
 
  ha_autocommit_or_rollback(thd, 1);
2754
 
  end_trans(thd, ROLLBACK);
2755
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
2760
  ha_autocommit_or_rollback(session, 1);
 
2761
  end_trans(session, ROLLBACK);
 
2762
  close_thread_tables(session);                 // Shouldn't be needed
2756
2763
  if (table)
2757
2764
    table->table=0;
2758
2765
  return(true);
2759
2766
}
2760
2767
 
2761
2768
 
2762
 
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2769
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2763
2770
{
2764
 
  return(mysql_admin_table(thd, tables, check_opt,
2765
 
                                "repair", TL_WRITE, 1,
2766
 
                                test(check_opt->sql_flags & TT_USEFRM),
2767
 
                                HA_OPEN_FOR_REPAIR,
2768
 
                                &prepare_for_repair,
2769
 
                                &handler::ha_repair));
 
2771
  return(mysql_admin_table(session, tables, check_opt,
 
2772
                           "repair", TL_WRITE, 1,
 
2773
                           check_opt->use_frm,
 
2774
                           HA_OPEN_FOR_REPAIR,
 
2775
                           &prepare_for_repair,
 
2776
                           &handler::ha_repair));
2770
2777
}
2771
2778
 
2772
2779
 
2773
 
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2780
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2774
2781
{
2775
 
  return(mysql_admin_table(thd, tables, check_opt,
2776
 
                                "optimize", TL_WRITE, 1,0,0,0,
2777
 
                                &handler::ha_optimize));
 
2782
  return(mysql_admin_table(session, tables, check_opt,
 
2783
                           "optimize", TL_WRITE, 1,0,0,0,
 
2784
                           &handler::ha_optimize));
2778
2785
}
2779
2786
 
2780
2787
 
2783
2790
 
2784
2791
  SYNOPSIS
2785
2792
    mysql_assign_to_keycache()
2786
 
    thd         Thread object
 
2793
    session             Thread object
2787
2794
    tables      Table list (one table only)
2788
2795
 
2789
2796
  RETURN VALUES
2791
2798
   true  error
2792
2799
*/
2793
2800
 
2794
 
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
 
2801
bool mysql_assign_to_keycache(Session* session, TableList* tables,
2795
2802
                             LEX_STRING *key_cache_name)
2796
2803
{
2797
2804
  HA_CHECK_OPT check_opt;
2807
2814
  }
2808
2815
  pthread_mutex_unlock(&LOCK_global_system_variables);
2809
2816
  check_opt.key_cache= key_cache;
2810
 
  return(mysql_admin_table(thd, tables, &check_opt,
 
2817
  return(mysql_admin_table(session, tables, &check_opt,
2811
2818
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
2812
2819
                                0, 0, &handler::assign_to_keycache));
2813
2820
}
2818
2825
 
2819
2826
  SYNOPSIS
2820
2827
    reassign_keycache_tables()
2821
 
    thd         Thread object
 
2828
    session             Thread object
2822
2829
    src_cache   Reference to the key cache to clean up
2823
2830
    dest_cache  New key cache
2824
2831
 
2838
2845
    0     ok
2839
2846
*/
2840
2847
 
2841
 
int reassign_keycache_tables(THD *thd __attribute__((unused)),
 
2848
int reassign_keycache_tables(Session *,
2842
2849
                             KEY_CACHE *src_cache,
2843
2850
                             KEY_CACHE *dst_cache)
2844
2851
{
2853
2860
/**
2854
2861
  @brief          Create frm file based on I_S table
2855
2862
 
2856
 
  @param[in]      thd                      thread handler
2857
 
  @param[in]      schema_table             I_S table           
 
2863
  @param[in]      session                      thread handler
 
2864
  @param[in]      schema_table             I_S table
2858
2865
  @param[in]      dst_path                 path where frm should be created
2859
2866
  @param[in]      create_info              Create info
2860
2867
 
2862
2869
    @retval       0                        success
2863
2870
    @retval       1                        error
2864
2871
*/
2865
 
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
 
2872
bool mysql_create_like_schema_frm(Session* session, TableList* schema_table,
2866
2873
                                  char *dst_path, HA_CREATE_INFO *create_info)
2867
2874
{
2868
2875
  HA_CREATE_INFO local_create_info;
2877
2884
  local_create_info.default_table_charset=default_charset_info;
2878
2885
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2879
2886
  schema_table->table->use_all_columns();
2880
 
  if (mysql_prepare_alter_table(thd, schema_table->table,
 
2887
  if (mysql_prepare_alter_table(session, schema_table->table,
2881
2888
                                &local_create_info, &alter_info))
2882
 
    return(1);
2883
 
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
 
2889
    return true;
 
2890
 
 
2891
  if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2884
2892
                                 tmp_table, &db_options,
2885
2893
                                 schema_table->table->file,
2886
2894
                                 &schema_table->table->s->key_info, &keys, 0))
2887
 
    return(1);
 
2895
    return true;
 
2896
 
2888
2897
  local_create_info.max_rows= 0;
2889
 
  if (mysql_create_frm(thd, dst_path, NULL, NULL,
 
2898
  if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
2890
2899
                       &local_create_info, alter_info.create_list,
2891
2900
                       keys, schema_table->table->s->key_info,
2892
 
                       schema_table->table->file))
2893
 
    return(1);
2894
 
  return(0);
 
2901
                       schema_table->table->file, true))
 
2902
    return true;
 
2903
 
 
2904
  return false;
2895
2905
}
2896
2906
 
2897
 
 
2898
2907
/*
2899
2908
  Create a table identical to the specified table
2900
2909
 
2901
2910
  SYNOPSIS
2902
2911
    mysql_create_like_table()
2903
 
    thd         Thread object
 
2912
    session             Thread object
2904
2913
    table       Table list element for target table
2905
2914
    src_table   Table list element for source table
2906
2915
    create_info Create info
2910
2919
    true  error
2911
2920
*/
2912
2921
 
2913
 
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
 
2922
bool mysql_create_like_table(Session* session, TableList* table, TableList* src_table,
2914
2923
                             HA_CREATE_INFO *create_info)
2915
2924
{
2916
2925
  Table *name_lock= 0;
2931
2940
    we ensure that our statement is properly isolated from all concurrent
2932
2941
    operations which matter.
2933
2942
  */
2934
 
  if (open_tables(thd, &src_table, &not_used, 0))
 
2943
  if (open_tables(session, &src_table, &not_used, 0))
2935
2944
    return(true);
2936
2945
 
2937
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
 
2946
  sprintf(src_path,"%s%s",src_table->table->s->path.str, reg_ext);
2938
2947
 
2939
 
  /* 
 
2948
  /*
2940
2949
    Check that destination tables does not exist. Note that its name
2941
2950
    was already checked when it was added to the table list.
2942
2951
  */
2943
2952
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2944
2953
  {
2945
 
    if (find_temporary_table(thd, db, table_name))
 
2954
    if (find_temporary_table(session, db, table_name))
2946
2955
      goto table_exists;
2947
 
    dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
 
2956
    dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2948
2957
    create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2949
2958
  }
2950
2959
  else
2951
2960
  {
2952
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
2961
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2953
2962
      goto err;
2954
2963
    if (!name_lock)
2955
2964
      goto table_exists;
2975
2984
  pthread_mutex_lock(&LOCK_open);
2976
2985
  if (src_table->schema_table)
2977
2986
  {
2978
 
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
 
2987
    if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
2979
2988
    {
2980
2989
      pthread_mutex_unlock(&LOCK_open);
2981
2990
      goto err;
2982
2991
    }
2983
2992
  }
2984
 
  else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
 
2993
  else
2985
2994
  {
2986
 
    if (my_errno == ENOENT)
2987
 
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2988
 
    else
2989
 
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2990
 
    pthread_mutex_unlock(&LOCK_open);
2991
 
    goto err;
 
2995
    int frmcopyr= my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE));
 
2996
 
 
2997
    string dfesrc(src_path);
 
2998
    string dfedst(dst_path);
 
2999
 
 
3000
    dfesrc.replace(dfesrc.find(".frm"), 4, ".dfe" );
 
3001
    dfedst.replace(dfedst.find(".frm"), 4, ".dfe" );
 
3002
 
 
3003
    int dfecopyr= my_copy(dfesrc.c_str(), dfedst.c_str(),
 
3004
                          MYF(MY_DONT_OVERWRITE_FILE));
 
3005
 
 
3006
    if(frmcopyr || dfecopyr) // FIXME: should handle only one fail.
 
3007
    {
 
3008
      if (my_errno == ENOENT)
 
3009
        my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
3010
      else
 
3011
        my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
 
3012
      pthread_mutex_unlock(&LOCK_open);
 
3013
      goto err;
 
3014
    }
2992
3015
  }
2993
3016
 
2994
3017
  /*
2997
3020
    and temporary tables).
2998
3021
  */
2999
3022
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
3000
 
  if (thd->variables.keep_files_on_create)
 
3023
  if (session->variables.keep_files_on_create)
3001
3024
    create_info->options|= HA_CREATE_KEEP_FILES;
3002
 
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
 
3025
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
3003
3026
  pthread_mutex_unlock(&LOCK_open);
3004
3027
 
3005
3028
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3006
3029
  {
3007
 
    if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
 
3030
    if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3008
3031
                                     OTM_OPEN))
3009
3032
    {
3010
3033
      (void) rm_temporary_table(create_info->db_type,
3011
 
                                dst_path, false); /* purecov: inspected */
 
3034
                                dst_path);
3012
3035
      goto err;     /* purecov: inspected */
3013
3036
    }
3014
3037
  }
3022
3045
  /*
3023
3046
    We have to write the query before we unlock the tables.
3024
3047
  */
3025
 
  if (thd->current_stmt_binlog_row_based)
3026
3048
  {
3027
3049
    /*
3028
3050
       Since temporary tables are not replicated under row-based
3056
3078
        */
3057
3079
        table->table= name_lock;
3058
3080
        pthread_mutex_lock(&LOCK_open);
3059
 
        if (reopen_name_locked_table(thd, table, false))
 
3081
        if (reopen_name_locked_table(session, table, false))
3060
3082
        {
3061
3083
          pthread_mutex_unlock(&LOCK_open);
3062
3084
          goto err;
3063
3085
        }
3064
3086
        pthread_mutex_unlock(&LOCK_open);
3065
3087
 
3066
 
        int result= store_create_info(thd, table, &query,
 
3088
        int result= store_create_info(session, table, &query,
3067
3089
                                               create_info);
3068
3090
 
3069
3091
        assert(result == 0); // store_create_info() always return 0
3070
 
        write_bin_log(thd, true, query.ptr(), query.length());
 
3092
        write_bin_log(session, true, query.ptr(), query.length());
3071
3093
      }
3072
3094
      else                                      // Case 1
3073
 
        write_bin_log(thd, true, thd->query, thd->query_length);
 
3095
        write_bin_log(session, true, session->query, session->query_length);
3074
3096
    }
3075
3097
    /*
3076
3098
      Case 3 and 4 does nothing under RBR
3077
3099
    */
3078
3100
  }
3079
 
  else
3080
 
    write_bin_log(thd, true, thd->query, thd->query_length);
3081
3101
 
3082
3102
  res= false;
3083
3103
  goto err;
3088
3108
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
3089
3109
    snprintf(warn_buff, sizeof(warn_buff),
3090
3110
             ER(ER_TABLE_EXISTS_ERROR), table_name);
3091
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3111
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3092
3112
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3093
3113
    res= false;
3094
3114
  }
3099
3119
  if (name_lock)
3100
3120
  {
3101
3121
    pthread_mutex_lock(&LOCK_open);
3102
 
    unlink_open_table(thd, name_lock, false);
 
3122
    unlink_open_table(session, name_lock, false);
3103
3123
    pthread_mutex_unlock(&LOCK_open);
3104
3124
  }
3105
3125
  return(res);
3106
3126
}
3107
3127
 
3108
3128
 
3109
 
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3129
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3110
3130
{
3111
3131
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3112
3132
 
3113
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3133
  return(mysql_admin_table(session, tables, check_opt,
3114
3134
                                "analyze", lock_type, 1, 0, 0, 0,
3115
3135
                                &handler::ha_analyze));
3116
3136
}
3117
3137
 
3118
3138
 
3119
 
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
 
3139
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3120
3140
{
3121
3141
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3122
3142
 
3123
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3143
  return(mysql_admin_table(session, tables, check_opt,
3124
3144
                                "check", lock_type,
3125
3145
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
3126
3146
                                &handler::ha_check));
3129
3149
 
3130
3150
/* table_list should contain just one table */
3131
3151
static int
3132
 
mysql_discard_or_import_tablespace(THD *thd,
 
3152
mysql_discard_or_import_tablespace(Session *session,
3133
3153
                                   TableList *table_list,
3134
3154
                                   enum tablespace_op_type tablespace_op)
3135
3155
{
3142
3162
    ALTER Table
3143
3163
  */
3144
3164
 
3145
 
  thd_proc_info(thd, "discard_or_import_tablespace");
 
3165
  session->set_proc_info("discard_or_import_tablespace");
3146
3166
 
3147
3167
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3148
3168
 
3150
3170
   We set this flag so that ha_innobase::open and ::external_lock() do
3151
3171
   not complain when we lock the table
3152
3172
 */
3153
 
  thd->tablespace_op= true;
3154
 
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
 
3173
  session->tablespace_op= true;
 
3174
  if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3155
3175
  {
3156
 
    thd->tablespace_op=false;
 
3176
    session->tablespace_op=false;
3157
3177
    return(-1);
3158
3178
  }
3159
3179
 
3160
3180
  error= table->file->ha_discard_or_import_tablespace(discard);
3161
3181
 
3162
 
  thd_proc_info(thd, "end");
 
3182
  session->set_proc_info("end");
3163
3183
 
3164
3184
  if (error)
3165
3185
    goto err;
3166
3186
 
3167
3187
  /* The ALTER Table is always in its own transaction */
3168
 
  error = ha_autocommit_or_rollback(thd, 0);
3169
 
  if (end_active_trans(thd))
 
3188
  error = ha_autocommit_or_rollback(session, 0);
 
3189
  if (end_active_trans(session))
3170
3190
    error=1;
3171
3191
  if (error)
3172
3192
    goto err;
3173
 
  write_bin_log(thd, false, thd->query, thd->query_length);
 
3193
  write_bin_log(session, false, session->query, session->query_length);
3174
3194
 
3175
3195
err:
3176
 
  ha_autocommit_or_rollback(thd, error);
3177
 
  thd->tablespace_op=false;
3178
 
  
 
3196
  ha_autocommit_or_rollback(session, error);
 
3197
  session->tablespace_op=false;
 
3198
 
3179
3199
  if (error == 0)
3180
3200
  {
3181
 
    my_ok(thd);
 
3201
    session->my_ok();
3182
3202
    return(0);
3183
3203
  }
3184
3204
 
3185
3205
  table->file->print_error(error, MYF(0));
3186
 
    
 
3206
 
3187
3207
  return(-1);
3188
3208
}
3189
3209
 
3223
3243
 
3224
3244
 
3225
3245
/**
3226
 
   @param       thd                Thread
 
3246
   @param       session                Thread
3227
3247
   @param       table              The original table.
3228
3248
   @param       alter_info         Alter options, fields and keys for the new
3229
3249
                                   table.
3255
3275
 
3256
3276
static
3257
3277
bool
3258
 
compare_tables(THD *thd,
 
3278
compare_tables(Session *session,
3259
3279
               Table *table,
3260
3280
               Alter_info *alter_info,
3261
 
                           HA_CREATE_INFO *create_info,
 
3281
               HA_CREATE_INFO *create_info,
3262
3282
               uint32_t order_num,
3263
3283
               HA_ALTER_FLAGS *alter_flags,
3264
3284
               HA_ALTER_INFO *ha_alter_info,
3270
3290
  Create_field *new_field;
3271
3291
  KEY_PART_INFO *key_part;
3272
3292
  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
3293
 
3279
3294
  {
3280
3295
    /*
3292
3307
      to evaluate possibility of fast ALTER Table, and then
3293
3308
      destroy the copy.
3294
3309
    */
3295
 
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
3296
 
    THD *thd= table->in_use;
 
3310
    Alter_info tmp_alter_info(*alter_info, session->mem_root);
 
3311
    session= table->in_use;
3297
3312
    uint32_t db_options= 0; /* not used */
3298
3313
    /* Create the prepared information. */
3299
 
    if (mysql_prepare_create_table(thd, create_info,
 
3314
    if (mysql_prepare_create_table(session, create_info,
3300
3315
                                   &tmp_alter_info,
3301
3316
                                   (table->s->tmp_table != NO_TMP_TABLE),
3302
3317
                                   &db_options,
3307
3322
      return(true);
3308
3323
    /* Allocate result buffers. */
3309
3324
    if (! (ha_alter_info->index_drop_buffer=
3310
 
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
 
3325
           (uint*) session->alloc(sizeof(uint) * table->s->keys)) ||
3311
3326
        ! (ha_alter_info->index_add_buffer=
3312
 
           (uint*) thd->alloc(sizeof(uint) *
 
3327
           (uint*) session->alloc(sizeof(uint) *
3313
3328
                              tmp_alter_info.key_list.elements)))
3314
3329
      return(true);
3315
3330
  }
3355
3370
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3356
3371
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3357
3372
      order_num ||
3358
 
      !table->s->mysql_version ||
3359
 
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
 
3373
      !table->s->mysql_version)
3360
3374
  {
3361
3375
    *table_changes= IS_EQUAL_NO;
3362
3376
    /*
3378
3392
    /* TODO check for ADD/DROP FOREIGN KEY */
3379
3393
    if (alter_info->flags & ALTER_FOREIGN_KEY)
3380
3394
      *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
3395
  }
3385
3396
  /*
3386
3397
    Go through fields and check if the original ones are compatible
3407
3418
      if (!(table_changes_local= field->is_equal(new_field)))
3408
3419
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3409
3420
 
 
3421
      /*
 
3422
        Check if the altered column is a stored virtual field.
 
3423
        TODO: Mark such a column with an alter flag only if
 
3424
        the expression functions are not equal.
 
3425
      */
 
3426
      if (field->is_stored && field->vcol_info)
 
3427
        *alter_flags|= HA_ALTER_STORED_VCOL;
 
3428
 
3410
3429
      /* Check if field was renamed */
3411
3430
      field->flags&= ~FIELD_IS_RENAMED;
3412
3431
      if (my_strcasecmp(system_charset_info,
3472
3491
      if (table_key->flags & HA_NOSAME)
3473
3492
      {
3474
3493
        /* Unique key. Check for "PRIMARY". */
3475
 
        if (! my_strcasecmp(system_charset_info,
3476
 
                            table_key->name, primary_key_name))
 
3494
        if (is_primary_key(table_key))
3477
3495
          *alter_flags|= HA_DROP_PK_INDEX;
3478
3496
        else
3479
3497
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
3493
3511
      if (table_key->flags & HA_NOSAME)
3494
3512
      {
3495
3513
        // Unique key. Check for "PRIMARY".
3496
 
        if (! my_strcasecmp(system_charset_info,
3497
 
                            table_key->name, primary_key_name))
 
3514
        if (is_primary_key(table_key))
3498
3515
          *alter_flags|= HA_ALTER_PK_INDEX;
3499
3516
        else
3500
3517
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3523
3540
        if (table_key->flags & HA_NOSAME)
3524
3541
        {
3525
3542
          /* Unique key. Check for "PRIMARY" */
3526
 
          if (! my_strcasecmp(system_charset_info,
3527
 
                              table_key->name, primary_key_name))
 
3543
          if (is_primary_key(table_key))
3528
3544
            *alter_flags|= HA_ALTER_PK_INDEX;
3529
3545
          else
3530
3546
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3586
3602
      if (new_key->flags & HA_NOSAME)
3587
3603
      {
3588
3604
        /* Unique key. Check for "PRIMARY" */
3589
 
        if (! my_strcasecmp(system_charset_info,
3590
 
                            new_key->name, primary_key_name))
 
3605
        if (is_primary_key(new_key))
3591
3606
          *alter_flags|= HA_ADD_PK_INDEX;
3592
3607
        else
3593
3608
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
3636
3651
 
3637
3652
  if (error == HA_ERR_WRONG_COMMAND)
3638
3653
  {
3639
 
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3654
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3640
3655
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3641
3656
                        table->s->table_name.str);
3642
3657
    error= 0;
3646
3661
  return(error);
3647
3662
}
3648
3663
 
3649
 
int create_temporary_table(THD *thd,
 
3664
int create_temporary_table(Session *session,
3650
3665
                           Table *table,
3651
3666
                           char *new_db,
3652
3667
                           char *tmp_name,
3688
3703
    if (create_info->index_file_name)
3689
3704
    {
3690
3705
      /* Fix index_file_name to have 'tmp_name' as basename */
3691
 
      my_stpcpy(index_file, tmp_name);
 
3706
      strcpy(index_file, tmp_name);
3692
3707
      create_info->index_file_name=fn_same(index_file,
3693
3708
                                           create_info->index_file_name,
3694
3709
                                           1);
3696
3711
    if (create_info->data_file_name)
3697
3712
    {
3698
3713
      /* Fix data_file_name to have 'tmp_name' as basename */
3699
 
      my_stpcpy(data_file, tmp_name);
 
3714
      strcpy(data_file, tmp_name);
3700
3715
      create_info->data_file_name=fn_same(data_file,
3701
3716
                                          create_info->data_file_name,
3702
3717
                                          1);
3707
3722
 
3708
3723
  /*
3709
3724
    Create a table with a temporary name.
3710
 
    With create_info->frm_only == 1 this creates a .frm file only.
3711
3725
    We don't log the statement, it will be logged later.
3712
3726
  */
3713
 
  tmp_disable_binlog(thd);
3714
 
  error= mysql_create_table(thd, new_db, tmp_name,
 
3727
  error= mysql_create_table(session, new_db, tmp_name,
3715
3728
                            create_info, alter_info, 1, 0);
3716
 
  reenable_binlog(thd);
3717
3729
 
3718
3730
  return(error);
3719
3731
}
3724
3736
 
3725
3737
  SYNOPSIS
3726
3738
    create_altered_table()
3727
 
      thd              Thread handle
 
3739
      session              Thread handle
3728
3740
      table            The original table
3729
3741
      create_info      Information from the parsing phase about new
3730
3742
                       table properties.
3738
3750
    The temporary table is created without storing it in any storage engine
3739
3751
    and is opened only to get the table struct and frm file reference.
3740
3752
*/
3741
 
Table *create_altered_table(THD *thd,
 
3753
Table *create_altered_table(Session *session,
3742
3754
                            Table *table,
3743
3755
                            char *new_db,
3744
3756
                            HA_CREATE_INFO *create_info,
3751
3763
  char tmp_name[80];
3752
3764
  char path[FN_REFLEN];
3753
3765
 
3754
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3755
 
           tmp_file_prefix, current_pid, thd->thread_id);
 
3766
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
 
3767
           TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3756
3768
  /* Safety fix for InnoDB */
3757
3769
  if (lower_case_table_names)
3758
3770
    my_casedn_str(files_charset_info, tmp_name);
3759
3771
  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,
 
3772
 
 
3773
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
3762
3774
                                     &altered_create_info,
3763
3775
                                     alter_info, db_change)))
3764
3776
  {
3767
3779
 
3768
3780
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
3769
3781
                       FN_IS_TMP);
3770
 
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
 
3782
  altered_table= open_temporary_table(session, path, new_db, tmp_name, 1,
3771
3783
                                      OTM_ALTER);
3772
3784
  return(altered_table);
3773
3785
 
3780
3792
 
3781
3793
  SYNOPSIS
3782
3794
    mysql_fast_or_online_alter_table()
3783
 
      thd              Thread handle
 
3795
      session              Thread handle
3784
3796
      table            The original table
3785
3797
      altered_table    A temporary table showing how we will change table
3786
3798
      create_info      Information from the parsing phase about new
3800
3812
    operation directly, on-line without mysql having to copy
3801
3813
    the table.
3802
3814
*/
3803
 
int mysql_fast_or_online_alter_table(THD *thd,
 
3815
int mysql_fast_or_online_alter_table(Session *session,
3804
3816
                                     Table *table,
3805
3817
                                     Table *altered_table,
3806
3818
                                     HA_CREATE_INFO *create_info,
3817
3829
   /*
3818
3830
      Tell the handler to prepare for the online alter
3819
3831
    */
3820
 
    if ((error= table->file->alter_table_phase1(thd,
 
3832
    if ((error= table->file->alter_table_phase1(session,
3821
3833
                                                altered_table,
3822
3834
                                                create_info,
3823
3835
                                                alter_info,
3828
3840
 
3829
3841
    /*
3830
3842
       Tell the storage engine to perform the online alter table
3831
 
       TODO: 
 
3843
       TODO:
3832
3844
       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
3833
3845
       we need to wrap the next call with a DDL lock.
3834
3846
     */
3835
 
    if ((error= table->file->alter_table_phase2(thd,
 
3847
    if ((error= table->file->alter_table_phase2(session,
3836
3848
                                                altered_table,
3837
3849
                                                create_info,
3838
3850
                                                alter_info,
3846
3858
    and will be renamed to the original table name.
3847
3859
  */
3848
3860
  pthread_mutex_lock(&LOCK_open);
3849
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
3861
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3850
3862
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3851
3863
                          keys_onoff);
3852
 
  close_data_files_and_morph_locks(thd,
 
3864
  close_data_files_and_morph_locks(session,
3853
3865
                                   table->pos_in_table_list->db,
3854
3866
                                   table->pos_in_table_list->table_name);
3855
3867
  if (mysql_rename_table(NULL,
3871
3883
    wait_if_global_read_lock(), which could create a deadlock if called
3872
3884
    with LOCK_open.
3873
3885
  */
3874
 
  error= ha_autocommit_or_rollback(thd, 0);
 
3886
  error= ha_autocommit_or_rollback(session, 0);
3875
3887
 
3876
 
  if (ha_commit(thd))
 
3888
  if (ha_commit(session))
3877
3889
    error=1;
3878
3890
  if (error)
3879
3891
    goto err;
3892
3904
      Tell the handler that the changed frm is on disk and table
3893
3905
      has been re-opened
3894
3906
   */
3895
 
    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
 
3907
    if ((error= t_table->file->alter_table_phase3(session, t_table)))
3896
3908
    {
3897
3909
      goto err;
3898
3910
    }
3931
3943
  instructions that require change in table data, not only in
3932
3944
  table definition or indexes.
3933
3945
 
3934
 
  @param[in,out]  thd         thread handle. Used as a memory pool
 
3946
  @param[in,out]  session         thread handle. Used as a memory pool
3935
3947
                              and source of environment information.
3936
3948
  @param[in]      table       the source table, open and locked
3937
3949
                              Used as an interface to the storage engine
3958
3970
*/
3959
3971
 
3960
3972
static bool
3961
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
3973
mysql_prepare_alter_table(Session *session, Table *table,
3962
3974
                          HA_CREATE_INFO *create_info,
3963
3975
                          Alter_info *alter_info)
3964
3976
{
4044
4056
    if (def)
4045
4057
    {                                           // Field is changed
4046
4058
      def->field=field;
 
4059
      if (field->is_stored != def->is_stored)
 
4060
      {
 
4061
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
4062
                 MYF(0),
 
4063
                 "Changing the STORED status");
 
4064
        goto err;
 
4065
      }
4047
4066
      if (!def->after)
4048
4067
        {
4049
4068
        new_create_list.push_back(def);
4095
4114
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4096
4115
      flag to allow ALTER Table only if the table to be altered is empty.
4097
4116
      */
4098
 
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
 
4117
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4099
4118
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4100
4119
         !alter_info->datetime_field &&
4101
4120
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4102
 
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
 
4121
         session->variables.sql_mode & MODE_NO_ZERO_DATE)
4103
4122
    {
4104
4123
        alter_info->datetime_field= def;
4105
4124
        alter_info->error_if_not_empty= true;
4135
4154
      */
4136
4155
      if (alter_info->build_method == HA_BUILD_ONLINE)
4137
4156
      {
4138
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4157
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4139
4158
        goto err;
4140
4159
      }
4141
4160
      alter_info->build_method= HA_BUILD_OFFLINE;
4242
4261
 
4243
4262
      if (key_info->flags & HA_NOSAME)
4244
4263
      {
4245
 
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
 
4264
        if (is_primary_key_name(key_name))
4246
4265
          key_type= Key::PRIMARY;
4247
4266
        else
4248
4267
          key_type= Key::UNIQUE;
4261
4280
    Key *key;
4262
4281
    while ((key=key_it++))                      // Add new keys
4263
4282
    {
 
4283
      if (key->type == Key::FOREIGN_KEY &&
 
4284
          ((Foreign_key *)key)->validate(new_create_list))
 
4285
        goto err;
4264
4286
      if (key->type != Key::FOREIGN_KEY)
4265
4287
        new_key_list.push_back(key);
4266
 
      if (key->name.str &&
4267
 
          !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
 
4288
      if (key->name.str && is_primary_key_name(key->name.str))
4268
4289
      {
4269
4290
        my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
4270
4291
        goto err;
4321
4342
 
4322
4343
  SYNOPSIS
4323
4344
    mysql_alter_table()
4324
 
      thd              Thread handle
 
4345
      session              Thread handle
4325
4346
      new_db           If there is a RENAME clause
4326
4347
      new_name         If there is a RENAME clause
4327
4348
      create_info      Information from the parsing phase about new
4358
4379
    true   Error
4359
4380
*/
4360
4381
 
4361
 
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 
4382
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4362
4383
                       HA_CREATE_INFO *create_info,
4363
4384
                       TableList *table_list,
4364
4385
                       Alter_info *alter_info,
4365
4386
                       uint32_t order_num, order_st *order, bool ignore)
4366
4387
{
4367
4388
  Table *table, *new_table=0, *name_lock= 0;;
 
4389
  string new_name_str;
4368
4390
  int error= 0;
4369
4391
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4370
4392
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4371
4393
  char path[FN_REFLEN];
4372
4394
  ha_rows copied= 0,deleted= 0;
4373
4395
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4374
 
  legacy_db_type table_type;
 
4396
 
 
4397
  new_name_buff[0]= '\0';
4375
4398
 
4376
4399
  if (table_list && table_list->schema_table)
4377
4400
  {
4378
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
4401
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4379
4402
    return(true);
4380
4403
  }
4381
4404
 
4384
4407
    to simplify further comparisons: we want to see if it's a RENAME
4385
4408
    later just by comparing the pointers, avoiding the need for strcmp.
4386
4409
  */
4387
 
  thd_proc_info(thd, "init");
 
4410
  session->set_proc_info("init");
4388
4411
  table_name=table_list->table_name;
4389
4412
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4390
4413
  db=table_list->db;
4392
4415
    new_db= db;
4393
4416
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
4394
4417
 
4395
 
  mysql_ha_rm_tables(thd, table_list, false);
 
4418
  mysql_ha_rm_tables(session, table_list, false);
4396
4419
 
4397
4420
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4398
4421
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4399
4422
    /* Conditionally writes to binlog. */
4400
 
    return(mysql_discard_or_import_tablespace(thd,table_list,
 
4423
    return(mysql_discard_or_import_tablespace(session,table_list,
4401
4424
                                              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);
 
4425
  ostringstream oss;
 
4426
  oss << drizzle_data_home << "/" << db << "/" << table_name << reg_ext;
 
4427
 
 
4428
  (void) unpack_filename(new_name_buff, oss.str().c_str());
4405
4429
  /*
4406
4430
    If this is just a rename of a view, short cut to the
4407
4431
    following scenario: 1) lock LOCK_open 2) do a RENAME
4415
4439
    into the main table list, like open_tables does).
4416
4440
    This code is wrong and will be removed, please do not copy.
4417
4441
  */
4418
 
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
4419
4442
 
4420
 
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
 
4443
  if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4421
4444
    return(true);
4422
4445
  table->use_all_columns();
4423
4446
 
4424
4447
  /* Check that we are not trying to rename to an existing table */
4425
4448
  if (new_name)
4426
4449
  {
4427
 
    my_stpcpy(new_name_buff,new_name);
4428
 
    my_stpcpy(new_alias= new_alias_buff, new_name);
 
4450
    strcpy(new_name_buff,new_name);
 
4451
    strcpy(new_alias= new_alias_buff, new_name);
4429
4452
    if (lower_case_table_names)
4430
4453
    {
4431
4454
      if (lower_case_table_names != 2)
4432
4455
      {
4433
 
        my_casedn_str(files_charset_info, new_name_buff);
4434
 
        new_alias= new_name;                    // Create lower case table name
 
4456
        my_casedn_str(files_charset_info, new_name_buff);
 
4457
        new_alias= new_name;                    // Create lower case table name
4435
4458
      }
4436
4459
      my_casedn_str(files_charset_info, new_name);
4437
4460
    }
4448
4471
    {
4449
4472
      if (table->s->tmp_table != NO_TMP_TABLE)
4450
4473
      {
4451
 
        if (find_temporary_table(thd,new_db,new_name_buff))
 
4474
        if (find_temporary_table(session,new_db,new_name_buff))
4452
4475
        {
4453
4476
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
4454
4477
          return(true);
4456
4479
      }
4457
4480
      else
4458
4481
      {
4459
 
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
 
4482
        if (lock_table_name_if_not_cached(session, new_db, new_name, &name_lock))
4460
4483
          return(true);
4461
4484
        if (!name_lock)
4462
4485
        {
4487
4510
    create_info->db_type= old_db_type;
4488
4511
  }
4489
4512
 
4490
 
  if (check_engine(thd, new_name, create_info))
 
4513
  if (check_engine(session, new_name, create_info))
4491
4514
    goto err;
4492
4515
  new_db_type= create_info->db_type;
4493
4516
 
4502
4525
  if (create_info->row_type == ROW_TYPE_NOT_USED)
4503
4526
    create_info->row_type= table->s->row_type;
4504
4527
 
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))
 
4528
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_ALTER_NOT_SUPPORTED) ||
 
4529
      ha_check_storage_engine_flag(new_db_type, HTON_BIT_ALTER_NOT_SUPPORTED))
4507
4530
  {
4508
4531
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4509
4532
    goto err;
4510
4533
  }
4511
4534
 
4512
 
  thd_proc_info(thd, "setup");
 
4535
  session->set_proc_info("setup");
4513
4536
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4514
4537
      !table->s->tmp_table) // no need to touch frm
4515
4538
  {
4527
4550
        from concurrent DDL statements.
4528
4551
      */
4529
4552
      pthread_mutex_lock(&LOCK_open);
4530
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4553
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4531
4554
      pthread_mutex_unlock(&LOCK_open);
4532
4555
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4533
4556
      /* COND_refresh will be signaled in close_thread_tables() */
4534
4557
      break;
4535
4558
    case DISABLE:
4536
4559
      pthread_mutex_lock(&LOCK_open);
4537
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4560
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4538
4561
      pthread_mutex_unlock(&LOCK_open);
4539
4562
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4540
4563
      /* COND_refresh will be signaled in close_thread_tables() */
4547
4570
    if (error == HA_ERR_WRONG_COMMAND)
4548
4571
    {
4549
4572
      error= 0;
4550
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4573
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4551
4574
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4552
4575
                          table->alias);
4553
4576
    }
4564
4587
 
4565
4588
    if (!error && (new_name != table_name || new_db != db))
4566
4589
    {
4567
 
      thd_proc_info(thd, "rename");
 
4590
      session->set_proc_info("rename");
4568
4591
      /*
4569
4592
        Then do a 'simple' rename of the table. First we need to close all
4570
4593
        instances of 'source' table.
4571
4594
      */
4572
 
      close_cached_table(thd, table);
 
4595
      close_cached_table(session, table);
4573
4596
      /*
4574
4597
        Then, we want check once again that target table does not exist.
4575
4598
        Actually the order of these two steps does not matter since
4600
4623
    if (error == HA_ERR_WRONG_COMMAND)
4601
4624
  {
4602
4625
      error= 0;
4603
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4626
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4604
4627
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4605
4628
                          table->alias);
4606
4629
  }
4607
4630
 
4608
4631
    if (!error)
4609
4632
    {
4610
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4611
 
      my_ok(thd);
 
4633
      write_bin_log(session, true, session->query, session->query_length);
 
4634
      session->my_ok();
4612
4635
  }
4613
4636
    else if (error > 0)
4614
4637
  {
4616
4639
      error= -1;
4617
4640
    }
4618
4641
    if (name_lock)
4619
 
      unlink_open_table(thd, name_lock, false);
 
4642
      unlink_open_table(session, name_lock, false);
4620
4643
    pthread_mutex_unlock(&LOCK_open);
4621
4644
    table_list->table= NULL;                    // For query cache
4622
4645
    return(error);
4637
4660
  */
4638
4661
  new_db_type= create_info->db_type;
4639
4662
 
4640
 
  if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
 
4663
  if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4641
4664
      goto err;
4642
4665
 
4643
 
  set_table_default_charset(thd, create_info, db);
4644
 
 
4645
 
 
4646
 
  if (thd->variables.old_alter_table
 
4666
  set_table_default_charset(session, create_info, db);
 
4667
 
 
4668
  if (session->variables.old_alter_table
4647
4669
      || (table->s->db_type() != create_info->db_type)
4648
4670
     )
4649
4671
  {
4650
4672
    if (alter_info->build_method == HA_BUILD_ONLINE)
4651
4673
    {
4652
 
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4674
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4653
4675
      goto err;
4654
4676
    }
4655
4677
    alter_info->build_method= HA_BUILD_OFFLINE;
4663
4685
    uint32_t table_changes= IS_EQUAL_YES;
4664
4686
    bool need_copy_table= true;
4665
4687
    /* Check how much the tables differ. */
4666
 
    if (compare_tables(thd, table, alter_info,
 
4688
    if (compare_tables(session, table, alter_info,
4667
4689
                       create_info, order_num,
4668
4690
                       &ha_alter_flags,
4669
4691
                       &ha_alter_info,
4686
4708
    if (new_name == table_name && new_db == db &&
4687
4709
        ha_alter_flags.is_set())
4688
4710
    {
4689
 
      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
 
4711
      Alter_info tmp_alter_info(*alter_info, session->mem_root);
4690
4712
 
4691
4713
      /*
4692
4714
        If no table rename,
4693
4715
        check if table can be altered on-line
4694
4716
      */
4695
 
      if (!(altered_table= create_altered_table(thd,
 
4717
      if (!(altered_table= create_altered_table(session,
4696
4718
                                                table,
4697
4719
                                                new_db,
4698
4720
                                                create_info,
4720
4742
      case HA_ALTER_NOT_SUPPORTED:
4721
4743
        if (alter_info->build_method == HA_BUILD_ONLINE)
4722
4744
        {
4723
 
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4724
 
          close_temporary_table(thd, altered_table, 1, 1);
 
4745
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
 
4746
          close_temporary_table(session, altered_table, 1, 1);
4725
4747
          goto err;
4726
4748
        }
4727
4749
        need_copy_table= true;
4728
4750
        break;
4729
4751
      case HA_ALTER_ERROR:
4730
4752
      default:
4731
 
        close_temporary_table(thd, altered_table, 1, 1);
 
4753
        close_temporary_table(session, altered_table, 1, 1);
4732
4754
        goto err;
4733
4755
      }
4734
4756
 
4739
4761
 
4740
4762
    if (!need_copy_table)
4741
4763
    {
4742
 
      error= mysql_fast_or_online_alter_table(thd,
 
4764
      error= mysql_fast_or_online_alter_table(session,
4743
4765
                                              table,
4744
4766
                                              altered_table,
4745
4767
                                              create_info,
4746
4768
                                              &ha_alter_info,
4747
4769
                                              &ha_alter_flags,
4748
4770
                                              alter_info->keys_onoff);
4749
 
      if (thd->lock)
 
4771
      if (session->lock)
4750
4772
      {
4751
 
        mysql_unlock_tables(thd, thd->lock);
4752
 
        thd->lock=0;
 
4773
        mysql_unlock_tables(session, session->lock);
 
4774
        session->lock=0;
4753
4775
      }
4754
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4776
      close_temporary_table(session, altered_table, 1, 1);
4755
4777
 
4756
4778
      if (error)
4757
4779
      {
4770
4792
    }
4771
4793
 
4772
4794
    if (altered_table)
4773
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4795
      close_temporary_table(session, altered_table, 1, 1);
4774
4796
  }
4775
4797
 
4776
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4777
 
           current_pid, thd->thread_id);
 
4798
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
 
4799
           (unsigned long)current_pid, session->thread_id);
4778
4800
  /* Safety fix for innodb */
4779
4801
  if (lower_case_table_names)
4780
4802
    my_casedn_str(files_charset_info, tmp_name);
4781
4803
 
4782
4804
 
4783
4805
  /* 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, 
 
4806
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
 
4807
                                     create_info, alter_info,
4786
4808
                                     !strcmp(db, new_db))))
4787
4809
  {
4788
4810
    goto err;
4795
4817
    memset(&tbl, 0, sizeof(tbl));
4796
4818
    tbl.db= new_db;
4797
4819
    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);
 
4820
    /* Table is in session->temporary_tables */
 
4821
    new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4800
4822
  }
4801
4823
  else
4802
4824
  {
4803
 
    char path[FN_REFLEN];
 
4825
    char tmp_path[FN_REFLEN];
4804
4826
    /* table is a normal table: Create temporary table in same directory */
4805
 
    build_table_filename(path, sizeof(path), new_db, tmp_name, "",
 
4827
    build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, "",
4806
4828
                         FN_IS_TMP);
4807
4829
    /* Open our intermediate table */
4808
 
    new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
 
4830
    new_table=open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
4809
4831
  }
4810
4832
  if (!new_table)
4811
4833
    goto err1;
4812
4834
 
4813
4835
  /* 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");
 
4836
  session->count_cuted_fields= CHECK_FIELD_WARN;        // calc cuted fields
 
4837
  session->cuted_fields=0L;
 
4838
  session->set_proc_info("copy to tmp table");
4817
4839
  copied=deleted=0;
4818
4840
  /*
4819
4841
    We do not copy data for MERGE tables. Only the children have data.
4833
4855
  else
4834
4856
  {
4835
4857
    pthread_mutex_lock(&LOCK_open);
4836
 
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
4858
    wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4837
4859
    pthread_mutex_unlock(&LOCK_open);
4838
4860
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4839
4861
                            alter_info->keys_onoff);
4840
 
    error= ha_autocommit_or_rollback(thd, 0);
4841
 
    if (end_active_trans(thd))
 
4862
    error= ha_autocommit_or_rollback(session, 0);
 
4863
    if (end_active_trans(session))
4842
4864
      error= 1;
4843
4865
  }
4844
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
4866
  /* We must not ignore bad input! */;
 
4867
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
4845
4868
 
4846
4869
  if (table->s->tmp_table != NO_TMP_TABLE)
4847
4870
  {
4849
4872
    if (error)
4850
4873
      goto err1;
4851
4874
    /* Close lock if this is a transactional table */
4852
 
    if (thd->lock)
 
4875
    if (session->lock)
4853
4876
    {
4854
 
      mysql_unlock_tables(thd, thd->lock);
4855
 
      thd->lock=0;
 
4877
      mysql_unlock_tables(session, session->lock);
 
4878
      session->lock=0;
4856
4879
    }
4857
4880
    /* Remove link to old table and rename the new one */
4858
 
    close_temporary_table(thd, table, 1, 1);
 
4881
    close_temporary_table(session, table, 1, 1);
4859
4882
    /* 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))
 
4883
    if (rename_temporary_table(session, new_table, new_db, new_name))
4861
4884
      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
4885
    goto end_temporary;
4866
4886
  }
4867
4887
 
4898
4918
       call to remove name-locks from table cache and list of open table.
4899
4919
  */
4900
4920
 
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);
 
4921
  session->set_proc_info("rename result table");
 
4922
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
 
4923
           (unsigned long)current_pid, session->thread_id);
4904
4924
  if (lower_case_table_names)
4905
4925
    my_casedn_str(files_charset_info, old_name);
4906
4926
 
4907
 
  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4908
 
  close_data_files_and_morph_locks(thd, db, table_name);
 
4927
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
 
4928
  close_data_files_and_morph_locks(session, db, table_name);
4909
4929
 
4910
4930
  error=0;
4911
4931
  save_old_db_type= old_db_type;
4949
4969
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4950
4970
 
4951
4971
end_online:
4952
 
  if (thd->locked_tables && new_name == table_name && new_db == db)
 
4972
  if (session->locked_tables && new_name == table_name && new_db == db)
4953
4973
  {
4954
 
    thd->in_lock_tables= 1;
4955
 
    error= reopen_tables(thd, 1, 1);
4956
 
    thd->in_lock_tables= 0;
 
4974
    session->in_lock_tables= 1;
 
4975
    error= reopen_tables(session, 1, 1);
 
4976
    session->in_lock_tables= 0;
4957
4977
    if (error)
4958
4978
      goto err_with_placeholders;
4959
4979
  }
4960
4980
  pthread_mutex_unlock(&LOCK_open);
4961
4981
 
4962
 
  thd_proc_info(thd, "end");
4963
 
 
4964
 
  assert(!(mysql_bin_log.is_open() &&
4965
 
                thd->current_stmt_binlog_row_based &&
4966
 
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4967
 
  write_bin_log(thd, true, thd->query, thd->query_length);
4968
 
 
4969
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
 
4982
  session->set_proc_info("end");
 
4983
 
 
4984
  write_bin_log(session, true, session->query, session->query_length);
 
4985
 
 
4986
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
4970
4987
  {
4971
4988
    /*
4972
4989
      For the alter table to be properly flushed to the logs, we
4973
4990
      have to open the new table.  If not, we get a problem on server
4974
4991
      shutdown. But we do not need to attach MERGE children.
4975
4992
    */
4976
 
    char path[FN_REFLEN];
 
4993
    char table_path[FN_REFLEN];
4977
4994
    Table *t_table;
4978
 
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
4979
 
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
 
4995
    build_table_filename(table_path, sizeof(table_path), new_db, table_name, "", 0);
 
4996
    t_table= open_temporary_table(session, table_path, new_db, tmp_name, false, OTM_OPEN);
4980
4997
    if (t_table)
4981
4998
    {
4982
4999
      intern_close_table(t_table);
4983
5000
      free(t_table);
4984
5001
    }
4985
5002
    else
4986
 
      sql_print_warning(_("Could not open table %s.%s after rename\n"),
4987
 
                        new_db,table_name);
 
5003
      errmsg_printf(ERRMSG_LVL_WARN,
 
5004
                    _("Could not open table %s.%s after rename\n"),
 
5005
                    new_db,table_name);
4988
5006
    ha_flush_logs(old_db_type);
4989
5007
  }
4990
5008
  table_list->table=0;                          // For query cache
4991
5009
 
4992
 
  if (thd->locked_tables && (new_name != table_name || new_db != db))
 
5010
  if (session->locked_tables && (new_name != table_name || new_db != db))
4993
5011
  {
4994
5012
    /*
4995
5013
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
4998
5016
      LOCK TABLES we can rely on close_thread_tables() doing this job.
4999
5017
    */
5000
5018
    pthread_mutex_lock(&LOCK_open);
5001
 
    unlink_open_table(thd, table, false);
5002
 
    unlink_open_table(thd, name_lock, false);
 
5019
    unlink_open_table(session, table, false);
 
5020
    unlink_open_table(session, name_lock, false);
5003
5021
    pthread_mutex_unlock(&LOCK_open);
5004
5022
  }
5005
5023
 
5006
5024
end_temporary:
5007
 
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5008
 
           (ulong) (copied + deleted), (ulong) deleted,
5009
 
           (ulong) thd->cuted_fields);
5010
 
  my_ok(thd, copied + deleted, 0L, tmp_name);
5011
 
  thd->some_tables_deleted=0;
5012
 
  return(false);
 
5025
  /*
 
5026
   * Field::store() may have called my_error().  If this is 
 
5027
   * the case, we must not send an ok packet, since 
 
5028
   * Diagnostics_area::is_set() will fail an assert.
 
5029
   */
 
5030
  if (! session->is_error())
 
5031
  {
 
5032
    snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 
5033
            (ulong) (copied + deleted), (ulong) deleted,
 
5034
            (ulong) session->cuted_fields);
 
5035
    session->my_ok(copied + deleted, 0L, tmp_name);
 
5036
    session->some_tables_deleted=0;
 
5037
    return false;
 
5038
  }
 
5039
  else
 
5040
  {
 
5041
    /* my_error() was called.  Return true (which means error...) */
 
5042
    return true;
 
5043
  }
5013
5044
 
5014
5045
err1:
5015
5046
  if (new_table)
5016
5047
  {
5017
5048
    /* close_temporary_table() frees the new_table pointer. */
5018
 
    close_temporary_table(thd, new_table, 1, 1);
 
5049
    close_temporary_table(session, new_table, 1, 1);
5019
5050
  }
5020
5051
  else
5021
5052
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5027
5058
    the table to be altered isn't empty.
5028
5059
    Report error here.
5029
5060
  */
5030
 
  if (alter_info->error_if_not_empty && thd->row_count)
 
5061
  if (alter_info->error_if_not_empty && session->row_count)
5031
5062
  {
5032
5063
    const char *f_val= 0;
5033
5064
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
5034
5065
    switch (alter_info->datetime_field->sql_type)
5035
5066
    {
5036
 
      case DRIZZLE_TYPE_NEWDATE:
 
5067
      case DRIZZLE_TYPE_DATE:
5037
5068
        f_val= "0000-00-00";
5038
5069
        t_type= DRIZZLE_TIMESTAMP_DATE;
5039
5070
        break;
5045
5076
        /* Shouldn't get here. */
5046
5077
        assert(0);
5047
5078
    }
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,
 
5079
    bool save_abort_on_warning= session->abort_on_warning;
 
5080
    session->abort_on_warning= true;
 
5081
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5051
5082
                                 f_val, strlength(f_val), t_type,
5052
5083
                                 alter_info->datetime_field->field_name);
5053
 
    thd->abort_on_warning= save_abort_on_warning;
 
5084
    session->abort_on_warning= save_abort_on_warning;
5054
5085
  }
5055
5086
  if (name_lock)
5056
5087
  {
5057
5088
    pthread_mutex_lock(&LOCK_open);
5058
 
    unlink_open_table(thd, name_lock, false);
 
5089
    unlink_open_table(session, name_lock, false);
5059
5090
    pthread_mutex_unlock(&LOCK_open);
5060
5091
  }
5061
5092
  return(true);
5066
5097
    being altered. To be safe under LOCK TABLES we should remove placeholders
5067
5098
    from list of open tables list and table cache.
5068
5099
  */
5069
 
  unlink_open_table(thd, table, false);
 
5100
  unlink_open_table(session, table, false);
5070
5101
  if (name_lock)
5071
 
    unlink_open_table(thd, name_lock, false);
 
5102
    unlink_open_table(session, name_lock, false);
5072
5103
  pthread_mutex_unlock(&LOCK_open);
5073
5104
  return(true);
5074
5105
}
5087
5118
  int error;
5088
5119
  Copy_field *copy,*copy_end;
5089
5120
  ulong found_count,delete_count;
5090
 
  THD *thd= current_thd;
 
5121
  Session *session= current_session;
5091
5122
  uint32_t length= 0;
5092
5123
  SORT_FIELD *sortorder;
5093
5124
  READ_RECORD info;
5102
5133
  /*
5103
5134
    Turn off recovery logging since rollback of an alter table is to
5104
5135
    delete the new table so there is no need to log the changes to it.
5105
 
    
 
5136
 
5106
5137
    This needs to be done before external_lock
5107
5138
  */
5108
 
  error= ha_enable_transaction(thd, false);
 
5139
  error= ha_enable_transaction(session, false);
5109
5140
  if (error)
5110
5141
    return(-1);
5111
 
  
 
5142
 
5112
5143
  if (!(copy= new Copy_field[to->s->fields]))
5113
5144
    return(-1);                         /* purecov: inspected */
5114
5145
 
5115
 
  if (to->file->ha_external_lock(thd, F_WRLCK))
 
5146
  if (to->file->ha_external_lock(session, F_WRLCK))
5116
5147
    return(-1);
5117
5148
 
5118
5149
  /* We need external lock before we can disable/enable keys */
5119
5150
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5120
5151
 
5121
5152
  /* We can abort alter table for any table type */
5122
 
  thd->abort_on_warning= !ignore;
 
5153
  session->abort_on_warning= !ignore;
5123
5154
 
5124
5155
  from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5125
5156
  to->file->ha_start_bulk_insert(from->file->stats.records);
5126
5157
 
5127
 
  save_sql_mode= thd->variables.sql_mode;
 
5158
  save_sql_mode= session->variables.sql_mode;
5128
5159
 
5129
5160
  List_iterator<Create_field> it(create);
5130
5161
  Create_field *def;
5149
5180
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5150
5181
    {
5151
5182
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
5152
 
      snprintf(warn_buff, sizeof(warn_buff), 
 
5183
      snprintf(warn_buff, sizeof(warn_buff),
5153
5184
               _("order_st BY ignored because there is a user-defined clustered "
5154
5185
                 "index in the table '%-.192s'"),
5155
5186
               from->s->table_name.str);
5156
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
5187
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5157
5188
                   warn_buff);
5158
5189
    }
5159
5190
    else
5160
5191
    {
5161
 
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5162
 
                                                MYF(MY_FAE | MY_ZEROFILL));
 
5192
      from->sort.io_cache= new IO_CACHE;
 
5193
      memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
 
5194
 
5163
5195
      memset(&tables, 0, sizeof(tables));
5164
5196
      tables.table= from;
5165
5197
      tables.alias= tables.table_name= from->s->table_name.str;
5166
5198
      tables.db= from->s->db.str;
5167
5199
      error= 1;
5168
5200
 
5169
 
      if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5170
 
          setup_order(thd, thd->lex->select_lex.ref_pointer_array,
 
5201
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
 
5202
          setup_order(session, session->lex->select_lex.ref_pointer_array,
5171
5203
                      &tables, fields, all_fields, order) ||
5172
5204
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5173
 
          (from->sort.found_records= filesort(thd, from, sortorder, length,
 
5205
          (from->sort.found_records= filesort(session, from, sortorder, length,
5174
5206
                                              (SQL_SELECT *) 0, HA_POS_ERROR,
5175
5207
                                              1, &examined_rows)) ==
5176
5208
          HA_POS_ERROR)
5180
5212
 
5181
5213
  /* Tell handler that we have values for all columns in the to table */
5182
5214
  to->use_all_columns();
5183
 
  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
 
5215
  init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
5184
5216
  if (ignore)
5185
5217
    to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5186
 
  thd->row_count= 0;
 
5218
  session->row_count= 0;
5187
5219
  restore_record(to, s->default_values);        // Create empty record
5188
5220
  while (!(error=info.read_record(&info)))
5189
5221
  {
5190
 
    if (thd->killed)
 
5222
    if (session->killed)
5191
5223
    {
5192
 
      thd->send_kill_message();
 
5224
      session->send_kill_message();
5193
5225
      error= 1;
5194
5226
      break;
5195
5227
    }
5196
 
    thd->row_count++;
 
5228
    session->row_count++;
5197
5229
    /* Return error if source table isn't empty. */
5198
5230
    if (error_if_not_empty)
5199
5231
    {
5207
5239
      else
5208
5240
        to->next_number_field->reset();
5209
5241
    }
5210
 
    
 
5242
 
5211
5243
    for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
5212
5244
    {
5213
5245
      copy_ptr->do_copy(copy_ptr);
5214
5246
    }
5215
5247
    prev_insert_id= to->file->next_insert_id;
 
5248
    update_virtual_fields_marked_for_write(to, false);
5216
5249
    error=to->file->ha_write_row(to->record[0]);
5217
5250
    to->auto_increment_field_not_null= false;
5218
5251
    if (error)
5255
5288
  }
5256
5289
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
5257
5290
 
5258
 
  if (ha_enable_transaction(thd, true))
 
5291
  if (ha_enable_transaction(session, true))
5259
5292
  {
5260
5293
    error= 1;
5261
5294
    goto err;
5265
5298
    Ensure that the new table is saved properly to disk so that we
5266
5299
    can do a rename
5267
5300
  */
5268
 
  if (ha_autocommit_or_rollback(thd, 0))
 
5301
  if (ha_autocommit_or_rollback(session, 0))
5269
5302
    error=1;
5270
 
  if (end_active_trans(thd))
 
5303
  if (end_active_trans(session))
5271
5304
    error=1;
5272
5305
 
5273
5306
 err:
5274
 
  thd->variables.sql_mode= save_sql_mode;
5275
 
  thd->abort_on_warning= 0;
 
5307
  session->variables.sql_mode= save_sql_mode;
 
5308
  session->abort_on_warning= 0;
5276
5309
  free_io_cache(from);
5277
5310
  *copied= found_count;
5278
5311
  *deleted=delete_count;
5279
5312
  to->file->ha_release_auto_increment();
5280
 
  if (to->file->ha_external_lock(thd,F_UNLCK))
 
5313
  if (to->file->ha_external_lock(session,F_UNLCK))
5281
5314
    error=1;
5282
5315
  return(error > 0 ? -1 : 0);
5283
5316
}
5288
5321
 
5289
5322
  SYNOPSIS
5290
5323
    mysql_recreate_table()
5291
 
    thd                 Thread handler
 
5324
    session                     Thread handler
5292
5325
    tables              Tables to recreate
5293
5326
 
5294
5327
 RETURN
5295
5328
    Like mysql_alter_table().
5296
5329
*/
5297
 
bool mysql_recreate_table(THD *thd, TableList *table_list)
 
5330
bool mysql_recreate_table(Session *session, TableList *table_list)
5298
5331
{
5299
5332
  HA_CREATE_INFO create_info;
5300
5333
  Alter_info alter_info;
5311
5344
  create_info.default_table_charset=default_charset_info;
5312
5345
  /* Force alter table to recreate table */
5313
5346
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5314
 
  return(mysql_alter_table(thd, NULL, NULL, &create_info,
 
5347
  return(mysql_alter_table(session, NULL, NULL, &create_info,
5315
5348
                                table_list, &alter_info, 0,
5316
5349
                                (order_st *) 0, 0));
5317
5350
}
5318
5351
 
5319
5352
 
5320
 
bool mysql_checksum_table(THD *thd, TableList *tables,
 
5353
bool mysql_checksum_table(Session *session, TableList *tables,
5321
5354
                          HA_CHECK_OPT *check_opt)
5322
5355
{
5323
5356
  TableList *table;
5324
5357
  List<Item> field_list;
5325
5358
  Item *item;
5326
 
  Protocol *protocol= thd->protocol;
 
5359
  Protocol *protocol= session->protocol;
5327
5360
 
5328
5361
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5329
5362
  item->maybe_null= 1;
5340
5373
    char table_name[NAME_LEN*2+2];
5341
5374
    Table *t;
5342
5375
 
5343
 
    strxmov(table_name, table->db ,".", table->table_name, NULL);
 
5376
    sprintf(table_name,"%s.%s",table->db,table->table_name);
5344
5377
 
5345
 
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5346
 
    thd->clear_error();                 // these errors shouldn't get client
 
5378
    t= table->table= open_n_lock_single_table(session, table, TL_READ);
 
5379
    session->clear_error();                     // these errors shouldn't get client
5347
5380
 
5348
5381
    protocol->prepare_for_resend();
5349
5382
    protocol->store(table_name, system_charset_info);
5352
5385
    {
5353
5386
      /* Table didn't exist */
5354
5387
      protocol->store_null();
5355
 
      thd->clear_error();
 
5388
      session->clear_error();
5356
5389
    }
5357
5390
    else
5358
5391
    {
5415
5448
          t->file->ha_rnd_end();
5416
5449
        }
5417
5450
      }
5418
 
      thd->clear_error();
5419
 
      close_thread_tables(thd);
 
5451
      session->clear_error();
 
5452
      close_thread_tables(session);
5420
5453
      table->table=0;                           // For query cache
5421
5454
    }
5422
5455
    if (protocol->write())
5423
5456
      goto err;
5424
5457
  }
5425
5458
 
5426
 
  my_eof(thd);
 
5459
  session->my_eof();
5427
5460
  return(false);
5428
5461
 
5429
5462
 err:
5430
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
5463
  close_thread_tables(session);                 // Shouldn't be needed
5431
5464
  if (table)
5432
5465
    table->table=0;
5433
5466
  return(true);
5434
5467
}
5435
5468
 
5436
 
static bool check_engine(THD *thd, const char *table_name,
 
5469
static bool check_engine(Session *session, const char *table_name,
5437
5470
                         HA_CREATE_INFO *create_info)
5438
5471
{
5439
5472
  handlerton **new_engine= &create_info->db_type;
5440
5473
  handlerton *req_engine= *new_engine;
5441
5474
  bool no_substitution= 1;
5442
 
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
 
5475
  if (!(*new_engine= ha_checktype(session, ha_legacy_type(req_engine),
5443
5476
                                  no_substitution, 1)))
5444
5477
    return true;
5445
5478
 
5446
5479
  if (req_engine && req_engine != *new_engine)
5447
5480
  {
5448
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5481
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5449
5482
                       ER_WARN_USING_OTHER_HANDLER,
5450
5483
                       ER(ER_WARN_USING_OTHER_HANDLER),
5451
5484
                       ha_resolve_storage_engine_name(*new_engine),
5452
5485
                       table_name);
5453
5486
  }
5454
5487
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5455
 
      ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
 
5488
      ha_check_storage_engine_flag(*new_engine, HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5456
5489
  {
5457
5490
    if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5458
5491
    {