~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Toru Maesaka
  • Date: 2008-12-10 18:33:08 UTC
  • mto: (670.1.11 devel)
  • mto: This revision was merged to the branch mainline in revision 672.
  • Revision ID: dev@torum.net-20081210183308-mb6a5x0sbl1dhc5c
Replaced MySQL's my_stpncpy() with libc and c++ calls

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
#include <drizzled/server_includes.h>
19
19
#include <storage/myisam/myisam.h>
20
 
#include <drizzled/sql_show.h>
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
#include <libdrizzle/gettext.h>
 
20
#include <drizzled/show.h>
 
21
#include <drizzled/error.h>
 
22
#include <drizzled/gettext.h>
 
23
#include <drizzled/data_home.h>
 
24
#include <drizzled/sql_parse.h>
 
25
#include <mysys/hash.h>
 
26
#include <drizzled/sql_lex.h>
 
27
#include <drizzled/session.h>
 
28
#include <drizzled/sql_base.h>
 
29
#include <drizzled/db.h>
 
30
#include <drizzled/replicator.h>
 
31
 
 
32
extern HASH lock_db_cache;
23
33
 
24
34
int creating_table= 0;        // How many mysql_create_table are running
25
35
 
26
 
const char *primary_key_name="PRIMARY";
 
36
 
 
37
bool is_primary_key(KEY *key_info)
 
38
{
 
39
  static const char * primary_key_name="PRIMARY";
 
40
  return (strcmp(key_info->name, primary_key_name)==0);
 
41
}
 
42
 
 
43
const char* is_primary_key_name(const char* key_name)
 
44
{
 
45
  static const char * primary_key_name="PRIMARY";
 
46
  if (strcmp(key_name, primary_key_name)==0)
 
47
    return key_name;
 
48
  else
 
49
    return NULL;
 
50
}
27
51
 
28
52
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
53
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
30
54
static int copy_data_between_tables(Table *from,Table *to,
31
55
                                    List<Create_field> &create, bool ignore,
32
 
                                    uint order_num, order_st *order,
 
56
                                    uint32_t order_num, order_st *order,
33
57
                                    ha_rows *copied,ha_rows *deleted,
34
58
                                    enum enum_enable_or_disable keys_onoff,
35
59
                                    bool error_if_not_empty);
36
60
 
37
 
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
38
 
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
 
61
static bool prepare_blob_field(Session *session, Create_field *sql_field);
 
62
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
39
63
static int
40
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
64
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
41
65
                           Alter_info *alter_info,
42
66
                           bool tmp_table,
43
 
                               uint *db_options,
 
67
                               uint32_t *db_options,
44
68
                               handler *file, KEY **key_info_buffer,
45
 
                               uint *key_count, int select_field_count);
 
69
                               uint32_t *key_count, int select_field_count);
46
70
static bool
47
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
71
mysql_prepare_alter_table(Session *session, Table *table,
48
72
                          HA_CREATE_INFO *create_info,
49
73
                          Alter_info *alter_info);
50
74
 
60
84
  RETURN
61
85
    Table name length.
62
86
*/
63
 
uint filename_to_tablename(const char *from, char *to, uint to_length)
 
87
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
64
88
{
65
 
  uint errors;
66
 
  uint res;
 
89
  uint32_t errors;
 
90
  uint32_t res;
67
91
 
68
 
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
 
92
  if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
69
93
  {
70
94
    /* Temporary table name. */
71
 
    res= (stpncpy(to, from, to_length) - to);
 
95
    res= strlen(strncpy(to, from, to_length));
72
96
  }
73
97
  else
74
98
  {
76
100
                    system_charset_info,  to, to_length, &errors);
77
101
    if (errors) // Old 5.0 name
78
102
    {
79
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
80
 
            to);
 
103
      strcpy(to, MYSQL50_TABLE_NAME_PREFIX);
 
104
      strncat(to, from, to_length-MYSQL50_TABLE_NAME_PREFIX_LENGTH-1);
 
105
      res= strlen(to);
81
106
      sql_print_error(_("Invalid (old?) table or database name '%s'"), from);
82
107
    }
83
108
  }
98
123
  RETURN
99
124
    File name length.
100
125
*/
101
 
 
102
 
uint tablename_to_filename(const char *from, char *to, uint to_length)
 
126
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
103
127
{
104
 
  uint errors, length;
 
128
  uint32_t errors, length;
105
129
 
106
130
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
107
131
                                 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)));
 
132
    return((uint) (strncpy(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
 
133
                           to_length-1) -
 
134
                           (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
111
135
  length= strconvert(system_charset_info, from,
112
136
                     &my_charset_filename, to, to_length, &errors);
113
137
  if (check_if_legal_tablename(to) &&
121
145
 
122
146
 
123
147
/*
124
 
  Creates path to a file: mysql_data_dir/db/table.ext
 
148
  Creates path to a file: drizzle_data_dir/db/table.ext
125
149
 
126
150
  SYNOPSIS
127
151
   build_table_filename()
137
161
  NOTES
138
162
 
139
163
    Uses database and table name, and extension to create
140
 
    a file name in mysql_data_dir. Database and table
 
164
    a file name in drizzle_data_dir. Database and table
141
165
    names are converted from system_charset_info into "fscs".
142
166
    Unless flags indicate a temporary table name.
143
167
    'db' is always converted.
150
174
    build_tmptable_filename() for them.
151
175
 
152
176
  RETURN
153
 
    path length
 
177
    path length on success, 0 on failure
154
178
*/
155
179
 
156
 
uint build_table_filename(char *buff, size_t bufflen, const char *db,
157
 
                          const char *table_name, const char *ext, uint flags)
 
180
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
 
181
                          const char *table_name, const char *ext, uint32_t flags)
158
182
{
 
183
  std::string table_path;
159
184
  char dbbuff[FN_REFLEN];
160
185
  char tbbuff[FN_REFLEN];
 
186
  int rootdir_len= strlen(FN_ROOTDIR);
161
187
 
162
188
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
 
    stpncpy(tbbuff, table_name, sizeof(tbbuff));
 
189
    strncpy(tbbuff, table_name, sizeof(tbbuff));
164
190
  else
165
 
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
166
 
 
167
 
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
168
 
 
169
 
  char *end = buff + bufflen;
170
 
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
171
 
  char *pos = stpncpy(buff, mysql_data_home, bufflen);
172
 
  int rootdir_len= strlen(FN_ROOTDIR);
173
 
  if (pos - rootdir_len >= buff &&
174
 
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
175
 
    pos= stpncpy(pos, FN_ROOTDIR, end - pos);
176
 
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
 
191
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
 
192
 
 
193
  tablename_to_filename(db, dbbuff, sizeof(dbbuff));
 
194
  table_path= drizzle_data_home;
 
195
  int without_rootdir= table_path.length()-rootdir_len;
 
196
 
 
197
  /* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
 
198
  if (without_rootdir >= 0)
 
199
  {
 
200
    char *tmp= (char*)table_path.c_str()+without_rootdir;
 
201
    if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
 
202
      table_path.append(FN_ROOTDIR);
 
203
  }
 
204
 
 
205
  table_path.append(dbbuff);
 
206
  table_path.append(FN_ROOTDIR);
177
207
#ifdef USE_SYMDIR
178
 
  unpack_dirname(buff, buff);
179
 
  pos= strend(buff);
 
208
  table_path.clear();
180
209
#endif
181
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
182
 
 
183
 
  return(pos - buff);
 
210
  table_path.append(tbbuff);
 
211
  table_path.append(ext);
 
212
 
 
213
  if (bufflen < table_path.length())
 
214
    return 0;
 
215
 
 
216
  strcpy(buff, table_path.c_str());
 
217
  return table_path.length();
184
218
}
185
219
 
186
220
 
187
221
/*
188
 
  Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
 
222
  Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
189
223
 
190
224
  SYNOPSIS
191
225
   build_tmptable_filename()
192
 
     thd                        The thread handle.
 
226
     session                    The thread handle.
193
227
     buff                       Where to write result in my_charset_filename.
194
228
     bufflen                    buff size
195
229
 
196
230
  NOTES
197
231
 
198
232
    Uses current_pid, thread_id, and tmp_table counter to create
199
 
    a file name in mysql_tmpdir.
 
233
    a file name in drizzle_tmpdir.
200
234
 
201
235
  RETURN
202
 
    path length
 
236
    path length on success, 0 on failure
203
237
*/
204
238
 
205
 
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
239
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
206
240
{
 
241
  uint32_t length;
 
242
  std::ostringstream path_str, post_tmpdir_str;
 
243
  std::string tmp;
207
244
 
208
 
  char *p= stpncpy(buff, mysql_tmpdir, bufflen);
209
 
  snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
210
 
              tmp_file_prefix, current_pid,
211
 
              thd->thread_id, thd->tmp_table++, reg_ext);
 
245
  path_str << drizzle_tmpdir;
 
246
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
 
247
  post_tmpdir_str << session->thread_id << session->tmp_table++ << reg_ext;
 
248
  tmp= post_tmpdir_str.str();
212
249
 
213
250
  if (lower_case_table_names)
214
 
  {
215
 
    /* Convert all except tmpdir to lower case */
216
 
    my_casedn_str(files_charset_info, p);
217
 
  }
218
 
 
219
 
  uint length= unpack_filename(buff, buff);
220
 
  return(length);
 
251
    std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
 
252
 
 
253
  path_str << tmp;
 
254
 
 
255
  if (bufflen < path_str.str().length())
 
256
    length= 0;
 
257
  else
 
258
    length= unpack_filename(buff, path_str.str().c_str());
 
259
 
 
260
  return length;
221
261
}
222
262
 
223
263
/*
224
264
  SYNOPSIS
225
265
    write_bin_log()
226
 
    thd                           Thread object
 
266
    session                           Thread object
227
267
    clear_error                   is clear_error to be called
228
268
    query                         Query to log
229
269
    query_length                  Length of query
236
276
    file
237
277
*/
238
278
 
239
 
void write_bin_log(THD *thd, bool clear_error,
240
 
                   char const *query, ulong query_length)
 
279
void write_bin_log(Session *session, bool,
 
280
                   char const *query, size_t query_length)
241
281
{
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
 
  }
 
282
  (void)replicator_statement(session, query, query_length);
249
283
}
250
284
 
251
285
 
254
288
 
255
289
  SYNOPSIS
256
290
   mysql_rm_table()
257
 
   thd                  Thread handle
 
291
   session                      Thread handle
258
292
   tables               List of tables to delete
259
293
   if_exists            If 1, don't give error if one table doesn't exists
260
294
 
273
307
 
274
308
*/
275
309
 
276
 
bool mysql_rm_table(THD *thd,TableList *tables, bool if_exists, bool drop_temporary)
 
310
bool mysql_rm_table(Session *session,TableList *tables, bool if_exists, bool drop_temporary)
277
311
{
278
312
  bool error, need_start_waiting= false;
279
313
 
280
314
  if (tables && tables->schema_table)
281
315
  {
282
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
316
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
283
317
    return(true);
284
318
  }
285
319
 
287
321
 
288
322
  if (!drop_temporary)
289
323
  {
290
 
    if (!thd->locked_tables &&
291
 
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
324
    if (!session->locked_tables &&
 
325
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
292
326
      return(true);
293
327
  }
294
328
 
297
331
    LOCK_open during wait_if_global_read_lock(), other threads could not
298
332
    close their tables. This would make a pretty deadlock.
299
333
  */
300
 
  error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
 
334
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0);
301
335
 
302
336
  if (need_start_waiting)
303
 
    start_waiting_global_read_lock(thd);
 
337
    start_waiting_global_read_lock(session);
304
338
 
305
339
  if (error)
306
340
    return(true);
307
 
  my_ok(thd);
 
341
  my_ok(session);
308
342
  return(false);
309
343
}
310
344
 
313
347
 
314
348
  SYNOPSIS
315
349
    mysql_rm_table_part2()
316
 
    thd                 Thread handler
 
350
    session                     Thread handler
317
351
    tables              Tables to drop
318
352
    if_exists           If set, don't give an error if table doesn't exists.
319
353
                        In this case we give an warning of level 'NOTE'
320
354
    drop_temporary      Only drop temporary tables
321
355
    drop_view           Allow to delete VIEW .frm
322
356
    dont_log_query      Don't write query to log files. This will also not
323
 
                        generate warnings if the handler files doesn't exists  
 
357
                        generate warnings if the handler files doesn't exists
324
358
 
325
359
  TODO:
326
360
    When logging to the binary log, we should log
338
372
   -1   Thread was killed
339
373
*/
340
374
 
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)
 
375
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
 
376
                         bool drop_temporary, bool dont_log_query)
344
377
{
345
378
  TableList *table;
346
379
  char path[FN_REFLEN], *alias;
347
 
  uint path_length;
 
380
  uint32_t path_length;
348
381
  String wrong_tables;
349
382
  int error= 0;
350
383
  int non_temp_tables_count= 0;
351
384
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
352
385
  String built_query;
353
386
 
354
 
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
387
  if (!dont_log_query)
355
388
  {
356
389
    built_query.set_charset(system_charset_info);
357
390
    if (if_exists)
360
393
      built_query.append("DROP Table ");
361
394
  }
362
395
 
363
 
  mysql_ha_rm_tables(thd, tables, false);
 
396
  mysql_ha_rm_tables(session, tables, false);
364
397
 
365
398
  pthread_mutex_lock(&LOCK_open);
366
399
 
378
411
      table->db_type= share->db_type();
379
412
  }
380
413
 
381
 
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
 
414
  if (!drop_temporary && lock_table_names_exclusively(session, tables))
382
415
  {
383
416
    pthread_mutex_unlock(&LOCK_open);
384
417
    return(1);
385
418
  }
386
419
 
387
420
  /* Don't give warnings for not found errors, as we already generate notes */
388
 
  thd->no_warnings_for_error= 1;
 
421
  session->no_warnings_for_error= 1;
389
422
 
390
423
  for (table= tables; table; table= table->next_local)
391
424
  {
392
425
    char *db=table->db;
393
426
    handlerton *table_type;
394
 
    enum legacy_db_type frm_db_type;
395
 
 
396
 
 
397
 
    error= drop_temporary_table(thd, table);
 
427
 
 
428
    error= drop_temporary_table(session, table);
398
429
 
399
430
    switch (error) {
400
431
    case  0:
402
433
      tmp_table_deleted= 1;
403
434
      continue;
404
435
    case -1:
405
 
      assert(thd->in_sub_stmt);
406
436
      error= 1;
407
437
      goto err_with_placeholders;
408
438
    default:
416
446
      being built.  The string always end in a comma and the comma
417
447
      will be chopped off before being written to the binary log.
418
448
      */
419
 
    if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
449
    if (!dont_log_query)
420
450
    {
421
451
      non_temp_tables_count++;
422
452
      /*
423
453
        Don't write the database name if it is the current one (or if
424
 
        thd->db is NULL).
 
454
        session->db is NULL).
425
455
      */
426
456
      built_query.append("`");
427
 
      if (thd->db == NULL || strcmp(db,thd->db) != 0)
 
457
      if (session->db == NULL || strcmp(db,session->db) != 0)
428
458
      {
429
459
        built_query.append(db);
430
460
        built_query.append("`.`");
438
468
    if (!drop_temporary)
439
469
    {
440
470
      Table *locked_table;
441
 
      abort_locked_tables(thd, db, table->table_name);
442
 
      remove_table_from_cache(thd, db, table->table_name,
 
471
      abort_locked_tables(session, db, table->table_name);
 
472
      remove_table_from_cache(session, db, table->table_name,
443
473
                              RTFC_WAIT_OTHER_THREAD_FLAG |
444
474
                              RTFC_CHECK_KILLED_FLAG);
445
475
      /*
446
476
        If the table was used in lock tables, remember it so that
447
477
        unlock_table_names can free it
448
478
      */
449
 
      if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
 
479
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
450
480
        table->table= locked_table;
451
481
 
452
 
      if (thd->killed)
 
482
      if (session->killed)
453
483
      {
454
484
        error= -1;
455
485
        goto err_with_placeholders;
461
491
                                        FN_IS_TMP : 0);
462
492
    }
463
493
    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)))
 
494
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(session, db, alias))))
 
495
        )
466
496
    {
467
497
      // Table was not found on disk and table can't be created from engine
468
498
      if (if_exists)
469
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
499
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
470
500
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
471
501
                            table->table_name);
472
502
      else
475
505
    else
476
506
    {
477
507
      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
508
      // Remove extension for delete
484
509
      *(end= path + path_length - reg_ext_length)= '\0';
485
 
      error= ha_delete_table(thd, table_type, path, db, table->table_name,
 
510
      error= ha_delete_table(session, path, db, table->table_name,
486
511
                             !dont_log_query);
487
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
488
 
          (if_exists || table_type == NULL))
 
512
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
 
513
          if_exists)
489
514
      {
490
515
        error= 0;
491
 
        thd->clear_error();
 
516
        session->clear_error();
492
517
      }
493
518
      if (error == HA_ERR_ROW_IS_REFERENCED)
494
519
      {
498
523
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
499
524
      {
500
525
        int new_error;
 
526
 
 
527
        /* for some weird-ass reason, we ignore the return code here
 
528
           and things work. */
 
529
        delete_table_proto_file(path);
 
530
 
501
531
        /* Delete the table definition file */
502
 
        stpcpy(end,reg_ext);
 
532
        strcpy(end,reg_ext);
503
533
        if (!(new_error=my_delete(path,MYF(MY_WME))))
504
534
        {
505
535
          some_tables_deleted=1;
520
550
    on the table name.
521
551
  */
522
552
  pthread_mutex_unlock(&LOCK_open);
523
 
  thd->thread_specific_used|= tmp_table_deleted;
 
553
  session->thread_specific_used|= tmp_table_deleted;
524
554
  error= 0;
525
555
  if (wrong_tables.length())
526
556
  {
538
568
  {
539
569
    if (!dont_log_query)
540
570
    {
541
 
      if (!thd->current_stmt_binlog_row_based ||
542
 
          (non_temp_tables_count > 0 && !tmp_table_deleted))
 
571
      if ((non_temp_tables_count > 0 && !tmp_table_deleted))
543
572
      {
544
573
        /*
545
574
          In this case, we are either using statement-based
548
577
          tables).  In this case, we can write the original query into
549
578
          the binary log.
550
579
         */
551
 
        write_bin_log(thd, !error, thd->query, thd->query_length);
 
580
        write_bin_log(session, !error, session->query, session->query_length);
552
581
      }
553
 
      else if (thd->current_stmt_binlog_row_based &&
554
 
               non_temp_tables_count > 0 &&
 
582
      else if (non_temp_tables_count > 0 &&
555
583
               tmp_table_deleted)
556
584
      {
557
585
        /*
568
596
        */
569
597
        built_query.chop();                  // Chop of the last comma
570
598
        built_query.append(" /* generated by server */");
571
 
        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
 
599
        write_bin_log(session, !error, built_query.ptr(), built_query.length());
572
600
      }
573
601
      /*
574
602
        The remaining cases are:
582
610
  }
583
611
  pthread_mutex_lock(&LOCK_open);
584
612
err_with_placeholders:
585
 
  unlock_table_names(thd, tables, (TableList*) 0);
 
613
  unlock_table_names(session, tables, (TableList*) 0);
586
614
  pthread_mutex_unlock(&LOCK_open);
587
 
  thd->no_warnings_for_error= 0;
 
615
  session->no_warnings_for_error= 0;
588
616
  return(error);
589
617
}
590
618
 
604
632
    != 0        Error
605
633
*/
606
634
 
607
 
bool quick_rm_table(handlerton *base,const char *db,
608
 
                    const char *table_name, uint flags)
 
635
bool quick_rm_table(handlerton *base __attribute__((unused)),const char *db,
 
636
                    const char *table_name, uint32_t flags)
609
637
{
610
638
  char path[FN_REFLEN];
611
639
  bool error= 0;
612
640
 
613
 
  uint path_length= build_table_filename(path, sizeof(path),
 
641
  uint32_t path_length= build_table_filename(path, sizeof(path),
614
642
                                         db, table_name, reg_ext, flags);
615
643
  if (my_delete(path,MYF(0)))
616
644
    error= 1; /* purecov: inspected */
 
645
 
617
646
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
618
 
  return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
 
647
 
 
648
  error|= delete_table_proto_file(path);
 
649
 
 
650
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
619
651
              error);
620
652
}
621
653
 
635
667
static int sort_keys(KEY *a, KEY *b)
636
668
{
637
669
  ulong a_flags= a->flags, b_flags= b->flags;
638
 
  
 
670
 
639
671
  if (a_flags & HA_NOSAME)
640
672
  {
641
673
    if (!(b_flags & HA_NOSAME))
645
677
      /* Sort NOT NULL keys before other keys */
646
678
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
647
679
    }
648
 
    if (a->name == primary_key_name)
 
680
    if (is_primary_key(a))
649
681
      return -1;
650
 
    if (b->name == primary_key_name)
 
682
    if (is_primary_key(b))
651
683
      return 1;
652
684
    /* Sort keys don't containing partial segments before others */
653
685
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
691
723
  TYPELIB tmp= *typelib;
692
724
  const char **cur_value= typelib->type_names;
693
725
  unsigned int *cur_length= typelib->type_lengths;
694
 
  *dup_val_count= 0;  
695
 
  
 
726
  *dup_val_count= 0;
 
727
 
696
728
  for ( ; tmp.count > 1; cur_value++, cur_length++)
697
729
  {
698
730
    tmp.type_names++;
731
763
                                uint32_t *max_length, uint32_t *tot_length)
732
764
{
733
765
  const char **pos;
734
 
  uint *len;
 
766
  uint32_t *len;
735
767
  *max_length= *tot_length= 0;
736
768
  for (pos= interval->type_names, len= interval->type_lengths;
737
769
       *pos ; pos++, len++)
738
770
  {
739
 
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
 
771
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
740
772
    *tot_length+= length;
741
773
    set_if_bigger(*max_length, (uint32_t)length);
742
774
  }
762
794
   1    Error
763
795
*/
764
796
 
765
 
int prepare_create_field(Create_field *sql_field, 
766
 
                         uint *blob_columns,
 
797
int prepare_create_field(Create_field *sql_field,
 
798
                         uint32_t *blob_columns,
767
799
                         int *timestamps, int *timestamps_with_niladic,
768
800
                         int64_t table_flags __attribute__((unused)))
769
801
{
802
834
                                     sql_field->charset, &dup_val_count))
803
835
      return(1);
804
836
    break;
805
 
  case DRIZZLE_TYPE_NEWDATE:  // Rest of string types
 
837
  case DRIZZLE_TYPE_DATE:  // Rest of string types
806
838
  case DRIZZLE_TYPE_TIME:
807
839
  case DRIZZLE_TYPE_DATETIME:
808
840
  case DRIZZLE_TYPE_NULL:
840
872
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
841
873
    break;
842
874
  }
843
 
  if (!(sql_field->flags & NOT_NULL_FLAG))
 
875
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
 
876
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
844
877
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
845
878
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
846
879
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
852
885
 
853
886
  SYNOPSIS
854
887
    mysql_prepare_create_table()
855
 
      thd                       Thread object.
 
888
      session                       Thread object.
856
889
      create_info               Create information (like MAX_ROWS).
857
890
      alter_info                List of columns and indexes to create
858
891
      tmp_table                 If a temporary table is to be created.
874
907
*/
875
908
 
876
909
static int
877
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
910
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
878
911
                           Alter_info *alter_info,
879
912
                           bool tmp_table,
880
 
                               uint *db_options,
 
913
                               uint32_t *db_options,
881
914
                               handler *file, KEY **key_info_buffer,
882
 
                               uint *key_count, int select_field_count)
 
915
                               uint32_t *key_count, int select_field_count)
883
916
{
884
917
  const char    *key_name;
885
918
  Create_field  *sql_field,*dup_field;
892
925
  int           select_field_pos,auto_increment=0;
893
926
  List_iterator<Create_field> it(alter_info->create_list);
894
927
  List_iterator<Create_field> it2(alter_info->create_list);
895
 
  uint total_uneven_bit_length= 0;
 
928
  uint32_t total_uneven_bit_length= 0;
896
929
 
897
930
  select_field_pos= alter_info->create_list.elements - select_field_count;
898
931
  null_fields=blob_columns=0;
926
959
                                                    MY_CS_BINSORT,MYF(0))))
927
960
    {
928
961
      char tmp[64];
929
 
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
930
 
              STRING_WITH_LEN("_bin"));
 
962
      char *tmp_pos= tmp;
 
963
      strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
 
964
      tmp_pos+= strlen(tmp);
 
965
      strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
931
966
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
932
967
      return(true);
933
968
    }
936
971
      Convert the default value from client character
937
972
      set into the column character set if necessary.
938
973
    */
939
 
    if (sql_field->def && 
 
974
    if (sql_field->def &&
940
975
        save_cs != sql_field->def->collation.collation &&
941
976
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
942
977
    {
978
1013
          occupied memory at the same time when we free this
979
1014
          sql_field -- at the end of execution.
980
1015
        */
981
 
        interval= sql_field->interval= typelib(thd->mem_root,
 
1016
        interval= sql_field->interval= typelib(session->mem_root,
982
1017
                                               sql_field->interval_list);
983
1018
        List_iterator<String> int_it(sql_field->interval_list);
984
1019
        String conv, *tmp;
985
1020
        char comma_buf[4];
986
 
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
987
 
                                          (uchar*) comma_buf + 
 
1021
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
 
1022
                                          (unsigned char*) comma_buf +
988
1023
                                          sizeof(comma_buf));
989
1024
        assert(comma_length > 0);
990
 
        for (uint i= 0; (tmp= int_it++); i++)
 
1025
        for (uint32_t i= 0; (tmp= int_it++); i++)
991
1026
        {
992
 
          uint lengthsp;
 
1027
          uint32_t lengthsp;
993
1028
          if (String::needs_conversion(tmp->length(), tmp->charset(),
994
1029
                                       cs, &dummy))
995
1030
          {
996
 
            uint cnv_errs;
 
1031
            uint32_t cnv_errs;
997
1032
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
998
 
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
 
1033
            interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
999
1034
                                                  conv.length());
1000
1035
            interval->type_lengths[i]= conv.length();
1001
1036
          }
1004
1039
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
1005
1040
                                       interval->type_lengths[i]);
1006
1041
          interval->type_lengths[i]= lengthsp;
1007
 
          ((uchar *)interval->type_names[i])[lengthsp]= '\0';
 
1042
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
1008
1043
        }
1009
1044
        sql_field->interval_list.empty(); // Don't need interval_list anymore
1010
1045
      }
1025
1060
            }
1026
1061
 
1027
1062
            /* else, the defaults yield the correct length for NULLs. */
1028
 
          } 
 
1063
          }
1029
1064
          else /* not NULL */
1030
1065
          {
1031
1066
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
1043
1078
    }
1044
1079
 
1045
1080
    sql_field->create_length_to_internal_length();
1046
 
    if (prepare_blob_field(thd, sql_field))
 
1081
    if (prepare_blob_field(session, sql_field))
1047
1082
      return(true);
1048
1083
 
1049
1084
    if (!(sql_field->flags & NOT_NULL_FLAG))
1085
1120
          sql_field->decimals=          dup_field->decimals;
1086
1121
          sql_field->create_length_to_internal_length();
1087
1122
          sql_field->unireg_check=      dup_field->unireg_check;
1088
 
          /* 
 
1123
          /*
1089
1124
            We're making one field from two, the result field will have
1090
1125
            dup_field->flags as flags. If we've incremented null_fields
1091
1126
            because of sql_field->flags, decrement it back.
1094
1129
            null_fields--;
1095
1130
          sql_field->flags=             dup_field->flags;
1096
1131
          sql_field->interval=          dup_field->interval;
 
1132
          sql_field->vcol_info=         dup_field->vcol_info;
 
1133
          sql_field->is_stored=      dup_field->is_stored;
1097
1134
          it2.remove();                 // Remove first (create) definition
1098
1135
          select_field_pos--;
1099
1136
          break;
1116
1153
  {
1117
1154
    assert(sql_field->charset != 0);
1118
1155
 
1119
 
    if (prepare_create_field(sql_field, &blob_columns, 
 
1156
    if (prepare_create_field(sql_field, &blob_columns,
1120
1157
                             &timestamps, &timestamps_with_niladic,
1121
1158
                             file->ha_table_flags()))
1122
1159
      return(true);
1125
1162
    sql_field->offset= record_offset;
1126
1163
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1127
1164
      auto_increment++;
1128
 
    record_offset+= sql_field->pack_length;
 
1165
    /*
 
1166
          For now skip fields that are not physically stored in the database
 
1167
          (virtual fields) and update their offset later
 
1168
          (see the next loop).
 
1169
        */
 
1170
    if (sql_field->is_stored)
 
1171
      record_offset+= sql_field->pack_length;
 
1172
  }
 
1173
  /* Update virtual fields' offset */
 
1174
  it.rewind();
 
1175
  while ((sql_field=it++))
 
1176
  {
 
1177
    if (not sql_field->is_stored)
 
1178
    {
 
1179
      sql_field->offset= record_offset;
 
1180
      record_offset+= sql_field->pack_length;
 
1181
    }
1129
1182
  }
1130
1183
  if (timestamps_with_niladic > 1)
1131
1184
  {
1157
1210
 
1158
1211
  List_iterator<Key> key_iterator(alter_info->key_list);
1159
1212
  List_iterator<Key> key_iterator2(alter_info->key_list);
1160
 
  uint key_parts=0, fk_key_count=0;
 
1213
  uint32_t key_parts=0, fk_key_count=0;
1161
1214
  bool primary_key=0,unique_key=0;
1162
1215
  Key *key, *key2;
1163
 
  uint tmp, key_number;
 
1216
  uint32_t tmp, key_number;
1164
1217
  /* special marker for keys to be ignored */
1165
1218
  static char ignore_key[1];
1166
1219
 
1172
1225
    if (key->type == Key::FOREIGN_KEY)
1173
1226
    {
1174
1227
      fk_key_count++;
 
1228
      if (((Foreign_key *)key)->validate(alter_info->create_list))
 
1229
        return true;
1175
1230
      Foreign_key *fk_key= (Foreign_key*) key;
1176
1231
      if (fk_key->ref_columns.elements &&
1177
1232
          fk_key->ref_columns.elements != fk_key->columns.elements)
1228
1283
    else
1229
1284
      (*key_count)--;
1230
1285
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
1231
 
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
 
1286
        is_primary_key_name(key->name.str))
1232
1287
    {
1233
1288
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1234
1289
      return(true);
1250
1305
  key_number=0;
1251
1306
  for (; (key=key_iterator++) ; key_number++)
1252
1307
  {
1253
 
    uint key_length=0;
 
1308
    uint32_t key_length=0;
1254
1309
    Key_part_spec *column;
1255
1310
 
1256
1311
    if (key->name.str == ignore_key)
1294
1349
    if (key_info->block_size)
1295
1350
      key_info->flags|= HA_USES_BLOCK_SIZE;
1296
1351
 
1297
 
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
1352
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
1298
1353
                                           key->key_create_info.comment.str,
1299
1354
                                           key->key_create_info.comment.str +
1300
1355
                                           key->key_create_info.comment.length,
1316
1371
    }
1317
1372
 
1318
1373
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
1319
 
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
 
1374
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
1320
1375
    {
1321
 
      uint length;
 
1376
      uint32_t length;
1322
1377
      Key_part_spec *dup_column;
1323
1378
 
1324
1379
      it.rewind();
1361
1416
            return(true);
1362
1417
          }
1363
1418
        }
 
1419
        if (not sql_field->is_stored)
 
1420
        {
 
1421
          /* Key fields must always be physically stored. */
 
1422
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
 
1423
          return(true);
 
1424
        }
 
1425
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
 
1426
        {
 
1427
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
 
1428
          return(true);
 
1429
        }
1364
1430
        if (!(sql_field->flags & NOT_NULL_FLAG))
1365
1431
        {
1366
1432
          if (key->type == Key::PRIMARY)
1399
1465
          if ((length=column->length) > max_key_length ||
1400
1466
              length > file->max_key_part_length())
1401
1467
          {
1402
 
            length=min(max_key_length, file->max_key_part_length());
 
1468
            length=cmin(max_key_length, file->max_key_part_length());
1403
1469
            if (key->type == Key::MULTIPLE)
1404
1470
            {
1405
1471
              /* not a critical problem */
1406
1472
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
1407
1473
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1408
1474
                       length);
1409
 
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1475
              push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1410
1476
                           ER_TOO_LONG_KEY, warn_buff);
1411
1477
              /* Align key length to multibyte char boundary */
1412
1478
              length-= length % sql_field->charset->mbmaxlen;
1445
1511
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1446
1512
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1447
1513
                   length);
1448
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1514
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1449
1515
                       ER_TOO_LONG_KEY, warn_buff);
1450
1516
          /* Align key length to multibyte char boundary */
1451
1517
          length-= length % sql_field->charset->mbmaxlen;
1487
1553
                       MYF(0));
1488
1554
            return(true);
1489
1555
          }
1490
 
          key_name=primary_key_name;
 
1556
          static const char pkey_name[]= "PRIMARY";
 
1557
          key_name=pkey_name;
1491
1558
          primary_key=1;
1492
1559
        }
1493
1560
        else if (!(key_name= key->name.str))
1528
1595
    return(true);
1529
1596
  }
1530
1597
  /* Sort keys in optimized order */
1531
 
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
 
1598
  my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
1532
1599
           (qsort_cmp) sort_keys);
1533
1600
  create_info->null_bits= null_fields;
1534
1601
 
1538
1605
  {
1539
1606
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1540
1607
 
1541
 
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
 
1608
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1542
1609
        !sql_field->def &&
1543
1610
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1544
1611
        (sql_field->flags & NOT_NULL_FLAG) &&
1580
1647
    apply it to the table.
1581
1648
*/
1582
1649
 
1583
 
static void set_table_default_charset(THD *thd,
1584
 
                                      HA_CREATE_INFO *create_info, char *db)
 
1650
static void set_table_default_charset(Session *session,
 
1651
                                      HA_CREATE_INFO *create_info, char *db)
1585
1652
{
1586
1653
  /*
1587
1654
    If the table character set was not given explicitly,
1592
1659
  {
1593
1660
    HA_CREATE_INFO db_info;
1594
1661
 
1595
 
    load_db_opt_by_name(thd, db, &db_info);
 
1662
    load_db_opt_by_name(session, db, &db_info);
1596
1663
 
1597
1664
    create_info->default_table_charset= db_info.default_table_charset;
1598
1665
  }
1612
1679
        In this case the error is given
1613
1680
*/
1614
1681
 
1615
 
static bool prepare_blob_field(THD *thd __attribute__((unused)),
 
1682
static bool prepare_blob_field(Session *session __attribute__((unused)),
1616
1683
                               Create_field *sql_field)
1617
1684
{
1618
1685
 
1623
1690
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1624
1691
    return(1);
1625
1692
  }
1626
 
    
 
1693
 
1627
1694
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1628
1695
  {
1629
1696
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1639
1706
 
1640
1707
 
1641
1708
/*
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
1709
  Create a table
1680
1710
 
1681
1711
  SYNOPSIS
1682
1712
    mysql_create_table_no_lock()
1683
 
    thd                 Thread object
 
1713
    session                     Thread object
1684
1714
    db                  Database
1685
1715
    table_name          Table name
1686
1716
    create_info         Create information (like MAX_ROWS)
1688
1718
    keys                List of keys to create
1689
1719
    internal_tmp_table  Set to 1 if this is an internal temporary table
1690
1720
                        (From ALTER Table)
1691
 
    select_field_count  
 
1721
    select_field_count
1692
1722
 
1693
1723
  DESCRIPTION
1694
1724
    If one creates a temporary table, this is automatically opened
1708
1738
    true  error
1709
1739
*/
1710
1740
 
1711
 
bool mysql_create_table_no_lock(THD *thd,
 
1741
bool mysql_create_table_no_lock(Session *session,
1712
1742
                                const char *db, const char *table_name,
1713
1743
                                HA_CREATE_INFO *create_info,
1714
1744
                                Alter_info *alter_info,
1715
1745
                                bool internal_tmp_table,
1716
 
                                uint select_field_count)
 
1746
                                uint32_t select_field_count,
 
1747
                                bool lock_open_lock)
1717
1748
{
1718
1749
  char          path[FN_REFLEN];
1719
 
  uint          path_length;
 
1750
  uint32_t          path_length;
1720
1751
  const char    *alias;
1721
1752
  uint          db_options, key_count;
1722
1753
  KEY           *key_info_buffer;
1729
1760
               MYF(0));
1730
1761
    return(true);
1731
1762
  }
1732
 
  if (check_engine(thd, table_name, create_info))
 
1763
  if (check_engine(session, table_name, create_info))
1733
1764
    return(true);
1734
1765
  db_options= create_info->table_options;
1735
1766
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1736
1767
    db_options|=HA_OPTION_PACK_RECORD;
1737
1768
  alias= table_case_name(create_info, table_name);
1738
 
  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
 
1769
  if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1739
1770
                              create_info->db_type)))
1740
1771
  {
1741
1772
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1742
1773
    return(true);
1743
1774
  }
1744
1775
 
1745
 
  set_table_default_charset(thd, create_info, (char*) db);
 
1776
  set_table_default_charset(session, create_info, (char*) db);
1746
1777
 
1747
 
  if (mysql_prepare_create_table(thd, create_info, alter_info,
 
1778
  if (mysql_prepare_create_table(session, create_info, alter_info,
1748
1779
                                 internal_tmp_table,
1749
1780
                                 &db_options, file,
1750
1781
                          &key_info_buffer, &key_count,
1754
1785
      /* Check if table exists */
1755
1786
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1756
1787
  {
1757
 
    path_length= build_tmptable_filename(thd, path, sizeof(path));
 
1788
    path_length= build_tmptable_filename(session, path, sizeof(path));
1758
1789
    create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1759
1790
  }
1760
 
  else  
 
1791
  else
1761
1792
  {
1762
1793
 #ifdef FN_DEVCHAR
1763
1794
    /* check if the table name contains FN_DEVCHAR when defined */
1773
1804
 
1774
1805
  /* Check if table already exists */
1775
1806
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1776
 
      find_temporary_table(thd, db, table_name))
 
1807
      find_temporary_table(session, db, table_name))
1777
1808
  {
1778
1809
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1779
1810
    {
1780
1811
      create_info->table_existed= 1;            // Mark that table existed
1781
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1812
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1782
1813
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1783
1814
                          alias);
1784
1815
      error= 0;
1788
1819
    goto err;
1789
1820
  }
1790
1821
 
1791
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
1822
  if (lock_open_lock)
 
1823
    pthread_mutex_lock(&LOCK_open);
1792
1824
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1793
1825
  {
1794
1826
    if (!access(path,F_OK))
1826
1858
  {
1827
1859
    bool create_if_not_exists =
1828
1860
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1829
 
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
 
1861
    int retcode = ha_table_exists_in_engine(session, db, table_name);
1830
1862
    switch (retcode)
1831
1863
    {
1832
1864
      case HA_ERR_NO_SUCH_TABLE:
1845
1877
    }
1846
1878
  }
1847
1879
 
1848
 
  thd_proc_info(thd, "creating table");
 
1880
  session->set_proc_info("creating table");
1849
1881
  create_info->table_existed= 0;                // Mark that table is created
1850
1882
 
1851
1883
#ifdef HAVE_READLINK
1864
1896
#endif /* HAVE_READLINK */
1865
1897
  {
1866
1898
    if (create_info->data_file_name)
1867
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1899
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1868
1900
                   "DATA DIRECTORY option ignored");
1869
1901
    if (create_info->index_file_name)
1870
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1902
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1871
1903
                   "INDEX DIRECTORY option ignored");
1872
1904
    create_info->data_file_name= create_info->index_file_name= 0;
1873
1905
  }
1874
1906
  create_info->table_options=db_options;
1875
1907
 
1876
1908
  path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1877
 
  if (rea_create_table(thd, path, db, table_name,
 
1909
  if (rea_create_table(session, path, db, table_name,
1878
1910
                       create_info, alter_info->create_list,
1879
1911
                       key_count, key_info_buffer, file))
1880
1912
    goto unlock_and_end;
1882
1914
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1883
1915
  {
1884
1916
    /* Open table and put in temporary table list */
1885
 
    if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
 
1917
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1886
1918
    {
1887
 
      (void) rm_temporary_table(create_info->db_type, path, false);
 
1919
      (void) rm_temporary_table(create_info->db_type, path);
1888
1920
      goto unlock_and_end;
1889
1921
    }
1890
 
    thd->thread_specific_used= true;
 
1922
    session->thread_specific_used= true;
1891
1923
  }
1892
1924
 
1893
1925
  /*
1898
1930
    Otherwise, the statement shall be binlogged.
1899
1931
   */
1900
1932
  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);
 
1933
      ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
 
1934
    write_bin_log(session, true, session->query, session->query_length);
1905
1935
  error= false;
1906
1936
unlock_and_end:
1907
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
1937
  if (lock_open_lock)
 
1938
    pthread_mutex_unlock(&LOCK_open);
1908
1939
 
1909
1940
err:
1910
 
  thd_proc_info(thd, "After create");
 
1941
  session->set_proc_info("After create");
1911
1942
  delete file;
1912
1943
  return(error);
1913
1944
 
1914
1945
warn:
1915
1946
  error= false;
1916
 
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1947
  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1917
1948
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1918
1949
                      alias);
1919
1950
  create_info->table_existed= 1;                // Mark that table existed
1925
1956
  Database locking aware wrapper for mysql_create_table_no_lock(),
1926
1957
*/
1927
1958
 
1928
 
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
 
1959
bool mysql_create_table(Session *session, const char *db, const char *table_name,
1929
1960
                        HA_CREATE_INFO *create_info,
1930
1961
                        Alter_info *alter_info,
1931
1962
                        bool internal_tmp_table,
1932
 
                        uint select_field_count)
 
1963
                        uint32_t select_field_count)
1933
1964
{
1934
1965
  Table *name_lock= 0;
1935
1966
  bool result;
1936
1967
 
1937
1968
  /* Wait for any database locks */
1938
1969
  pthread_mutex_lock(&LOCK_lock_db);
1939
 
  while (!thd->killed &&
1940
 
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
 
1970
  while (!session->killed &&
 
1971
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
1941
1972
  {
1942
 
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1973
    wait_for_condition(session, &LOCK_lock_db, &COND_refresh);
1943
1974
    pthread_mutex_lock(&LOCK_lock_db);
1944
1975
  }
1945
1976
 
1946
 
  if (thd->killed)
 
1977
  if (session->killed)
1947
1978
  {
1948
1979
    pthread_mutex_unlock(&LOCK_lock_db);
1949
1980
    return(true);
1953
1984
 
1954
1985
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1955
1986
  {
1956
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
1987
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
1957
1988
    {
1958
1989
      result= true;
1959
1990
      goto unlock;
1962
1993
    {
1963
1994
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1964
1995
      {
1965
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1996
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1966
1997
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1967
1998
                            table_name);
1968
1999
        create_info->table_existed= 1;
1977
2008
    }
1978
2009
  }
1979
2010
 
1980
 
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
 
2011
  result= mysql_create_table_no_lock(session, db, table_name, create_info,
1981
2012
                                     alter_info,
1982
2013
                                     internal_tmp_table,
1983
 
                                     select_field_count);
 
2014
                                     select_field_count, true);
1984
2015
 
1985
2016
unlock:
1986
2017
  if (name_lock)
1987
2018
  {
1988
2019
    pthread_mutex_lock(&LOCK_open);
1989
 
    unlink_open_table(thd, name_lock, false);
 
2020
    unlink_open_table(session, name_lock, false);
1990
2021
    pthread_mutex_unlock(&LOCK_open);
1991
2022
  }
1992
2023
  pthread_mutex_lock(&LOCK_lock_db);
2017
2048
  char buff[MAX_FIELD_NAME],*buff_end;
2018
2049
 
2019
2050
  if (!check_if_keyname_exists(field_name,start,end) &&
2020
 
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
 
2051
      !is_primary_key_name(field_name))
2021
2052
    return (char*) field_name;                  // Use fieldname
2022
 
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
 
2053
 
 
2054
  buff_end= strncpy(buff, field_name, sizeof(buff)-4);
 
2055
  buff_end+= strlen(buff);
2023
2056
 
2024
2057
  /*
2025
2058
    Only 3 chars + '\0' left, so need to limit to 2 digit
2026
2059
    This is ok as we can't have more than 100 keys anyway
2027
2060
  */
2028
 
  for (uint i=2 ; i< 100; i++)
 
2061
  for (uint32_t i=2 ; i< 100; i++)
2029
2062
  {
2030
2063
    *buff_end= '_';
2031
2064
    int10_to_str(i, buff_end+1, 10);
2065
2098
bool
2066
2099
mysql_rename_table(handlerton *base, const char *old_db,
2067
2100
                   const char *old_name, const char *new_db,
2068
 
                   const char *new_name, uint flags)
 
2101
                   const char *new_name, uint32_t flags)
2069
2102
{
2070
 
  THD *thd= current_thd;
 
2103
  Session *session= current_session;
2071
2104
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2072
2105
  char *from_base= from, *to_base= to;
2073
2106
  char tmp_name[NAME_LEN+1];
2075
2108
  int error=0;
2076
2109
 
2077
2110
  file= (base == NULL ? 0 :
2078
 
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
 
2111
         get_new_handler((TABLE_SHARE*) 0, session->mem_root, base));
2079
2112
 
2080
2113
  build_table_filename(from, sizeof(from), old_db, old_name, "",
2081
2114
                       flags & FN_FROM_IS_TMP);
2090
2123
  if (lower_case_table_names == 2 && file &&
2091
2124
      !(file->ha_table_flags() & HA_FILE_BASED))
2092
2125
  {
2093
 
    stpcpy(tmp_name, old_name);
 
2126
    strcpy(tmp_name, old_name);
2094
2127
    my_casedn_str(files_charset_info, tmp_name);
2095
2128
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2096
2129
                         flags & FN_FROM_IS_TMP);
2097
2130
    from_base= lc_from;
2098
2131
 
2099
 
    stpcpy(tmp_name, new_name);
 
2132
    strcpy(tmp_name, new_name);
2100
2133
    my_casedn_str(files_charset_info, tmp_name);
2101
2134
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2102
2135
                         flags & FN_TO_IS_TMP);
2111
2144
      if (file)
2112
2145
        file->ha_rename_table(to_base, from_base);
2113
2146
    }
 
2147
 
 
2148
    if(!(flags & NO_FRM_RENAME)
 
2149
       && rename_table_proto_file(from_base, to_base))
 
2150
    {
 
2151
      error= errno;
 
2152
      rename_file_ext(to, from, reg_ext);
 
2153
      if (file)
 
2154
        file->ha_rename_table(to_base, from_base);
 
2155
    }
2114
2156
  }
2115
2157
  delete file;
2116
2158
  if (error == HA_ERR_WRONG_COMMAND)
2126
2168
 
2127
2169
  SYNOPSIS
2128
2170
    wait_while_table_is_used()
2129
 
    thd                 Thread handler
 
2171
    session                     Thread handler
2130
2172
    table               Table to remove from cache
2131
2173
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2132
2174
                        HA_EXTRA_FORCE_REOPEN if table is not be used
2140
2182
    Win32 clients must also have a WRITE LOCK on the table !
2141
2183
*/
2142
2184
 
2143
 
void wait_while_table_is_used(THD *thd, Table *table,
 
2185
void wait_while_table_is_used(Session *session, Table *table,
2144
2186
                              enum ha_extra_function function)
2145
2187
{
2146
2188
 
2147
2189
  safe_mutex_assert_owner(&LOCK_open);
2148
2190
 
2149
 
  VOID(table->file->extra(function));
 
2191
  table->file->extra(function);
2150
2192
  /* Mark all tables that are in use as 'old' */
2151
 
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
 
2193
  mysql_lock_abort(session, table, true);       /* end threads waiting on lock */
2152
2194
 
2153
2195
  /* Wait until all there are no other threads that has this table open */
2154
 
  remove_table_from_cache(thd, table->s->db.str,
 
2196
  remove_table_from_cache(session, table->s->db.str,
2155
2197
                          table->s->table_name.str,
2156
2198
                          RTFC_WAIT_OTHER_THREAD_FLAG);
2157
2199
  return;
2162
2204
 
2163
2205
  SYNOPSIS
2164
2206
    close_cached_table()
2165
 
    thd                 Thread handler
 
2207
    session                     Thread handler
2166
2208
    table               Table to remove from cache
2167
2209
 
2168
2210
  NOTES
2174
2216
    Win32 clients must also have a WRITE LOCK on the table !
2175
2217
*/
2176
2218
 
2177
 
void close_cached_table(THD *thd, Table *table)
 
2219
void close_cached_table(Session *session, Table *table)
2178
2220
{
2179
2221
 
2180
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
2222
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2181
2223
  /* Close lock if this is not got with LOCK TABLES */
2182
 
  if (thd->lock)
 
2224
  if (session->lock)
2183
2225
  {
2184
 
    mysql_unlock_tables(thd, thd->lock);
2185
 
    thd->lock=0;                        // Start locked threads
 
2226
    mysql_unlock_tables(session, session->lock);
 
2227
    session->lock=0;                    // Start locked threads
2186
2228
  }
2187
2229
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
2188
 
  unlink_open_table(thd, table, true);
 
2230
  unlink_open_table(session, table, true);
2189
2231
 
2190
2232
  /* When lock on LOCK_open is freed other threads can continue */
2191
2233
  broadcast_refresh();
2192
2234
  return;
2193
2235
}
2194
2236
 
2195
 
static int send_check_errmsg(THD *thd, TableList* table,
 
2237
static int send_check_errmsg(Session *session, TableList* table,
2196
2238
                             const char* operator_name, const char* errmsg)
2197
2239
 
2198
2240
{
2199
 
  Protocol *protocol= thd->protocol;
 
2241
  Protocol *protocol= session->protocol;
2200
2242
  protocol->prepare_for_resend();
2201
2243
  protocol->store(table->alias, system_charset_info);
2202
2244
  protocol->store((char*) operator_name, system_charset_info);
2203
2245
  protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2204
2246
  protocol->store(errmsg, system_charset_info);
2205
 
  thd->clear_error();
 
2247
  session->clear_error();
2206
2248
  if (protocol->write())
2207
2249
    return -1;
2208
2250
  return 1;
2209
2251
}
2210
2252
 
2211
2253
 
2212
 
static int prepare_for_repair(THD *thd, TableList *table_list,
 
2254
static int prepare_for_repair(Session *session, TableList *table_list,
2213
2255
                              HA_CHECK_OPT *check_opt)
2214
2256
{
2215
2257
  int error= 0;
2225
2267
  if (!(table= table_list->table))              /* if open_ltable failed */
2226
2268
  {
2227
2269
    char key[MAX_DBKEY_LENGTH];
2228
 
    uint key_length;
 
2270
    uint32_t key_length;
2229
2271
 
2230
 
    key_length= create_table_def_key(thd, key, table_list, 0);
 
2272
    key_length= create_table_def_key(session, key, table_list, 0);
2231
2273
    pthread_mutex_lock(&LOCK_open);
2232
 
    if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
 
2274
    if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2233
2275
                                  &error))))
2234
2276
    {
2235
2277
      pthread_mutex_unlock(&LOCK_open);
2236
2278
      return(0);                                // Can't open frm file
2237
2279
    }
2238
2280
 
2239
 
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
 
2281
    if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2240
2282
    {
2241
2283
      release_table_share(share, RELEASE_NORMAL);
2242
2284
      pthread_mutex_unlock(&LOCK_open);
2251
2293
  */
2252
2294
  if (table->s->tmp_table)
2253
2295
  {
2254
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2296
    error= send_check_errmsg(session, table_list, "repair",
2255
2297
                             "Cannot repair temporary table from .frm file");
2256
2298
    goto end;
2257
2299
  }
2270
2312
    Check if this is a table type that stores index and data separately,
2271
2313
    like ISAM or MyISAM. We assume fixed order of engine file name
2272
2314
    extentions array. First element of engine file name extentions array
2273
 
    is meta/index file extention. Second element - data file extention. 
 
2315
    is meta/index file extention. Second element - data file extention.
2274
2316
  */
2275
2317
  ext= table->file->bas_ext();
2276
2318
  if (!ext[0] || !ext[1])
2277
2319
    goto end;                                   // No data file
2278
2320
 
2279
2321
  // Name of data file
2280
 
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
 
2322
  strxmov(from, table->s->normalized_path.str, ext[1], NULL);
2281
2323
  if (stat(from, &stat_info))
2282
2324
    goto end;                           // Can't use USE_FRM flag
2283
2325
 
2284
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2285
 
           from, current_pid, thd->thread_id);
 
2326
  snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
 
2327
           from, (unsigned long)current_pid, session->thread_id);
2286
2328
 
2287
2329
  /* If we could open the table, close it */
2288
2330
  if (table_list->table)
2289
2331
  {
2290
2332
    pthread_mutex_lock(&LOCK_open);
2291
 
    close_cached_table(thd, table);
 
2333
    close_cached_table(session, table);
2292
2334
    pthread_mutex_unlock(&LOCK_open);
2293
2335
  }
2294
 
  if (lock_and_wait_for_table_name(thd,table_list))
 
2336
  if (lock_and_wait_for_table_name(session,table_list))
2295
2337
  {
2296
2338
    error= -1;
2297
2339
    goto end;
2299
2341
  if (my_rename(from, tmp, MYF(MY_WME)))
2300
2342
  {
2301
2343
    pthread_mutex_lock(&LOCK_open);
2302
 
    unlock_table_name(thd, table_list);
 
2344
    unlock_table_name(session, table_list);
2303
2345
    pthread_mutex_unlock(&LOCK_open);
2304
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2346
    error= send_check_errmsg(session, table_list, "repair",
2305
2347
                             "Failed renaming data file");
2306
2348
    goto end;
2307
2349
  }
2308
 
  if (mysql_truncate(thd, table_list, 1))
 
2350
  if (mysql_truncate(session, table_list, 1))
2309
2351
  {
2310
2352
    pthread_mutex_lock(&LOCK_open);
2311
 
    unlock_table_name(thd, table_list);
 
2353
    unlock_table_name(session, table_list);
2312
2354
    pthread_mutex_unlock(&LOCK_open);
2313
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2355
    error= send_check_errmsg(session, table_list, "repair",
2314
2356
                             "Failed generating table from .frm file");
2315
2357
    goto end;
2316
2358
  }
2317
2359
  if (my_rename(tmp, from, MYF(MY_WME)))
2318
2360
  {
2319
2361
    pthread_mutex_lock(&LOCK_open);
2320
 
    unlock_table_name(thd, table_list);
 
2362
    unlock_table_name(session, table_list);
2321
2363
    pthread_mutex_unlock(&LOCK_open);
2322
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2364
    error= send_check_errmsg(session, table_list, "repair",
2323
2365
                             "Failed restoring .MYD file");
2324
2366
    goto end;
2325
2367
  }
2329
2371
    to finish the repair in the handler later on.
2330
2372
  */
2331
2373
  pthread_mutex_lock(&LOCK_open);
2332
 
  if (reopen_name_locked_table(thd, table_list, true))
 
2374
  if (reopen_name_locked_table(session, table_list, true))
2333
2375
  {
2334
 
    unlock_table_name(thd, table_list);
 
2376
    unlock_table_name(session, table_list);
2335
2377
    pthread_mutex_unlock(&LOCK_open);
2336
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2378
    error= send_check_errmsg(session, table_list, "repair",
2337
2379
                             "Failed to open partially repaired table");
2338
2380
    goto end;
2339
2381
  }
2354
2396
/*
2355
2397
  RETURN VALUES
2356
2398
    false Message sent to net (admin operation went ok)
2357
 
    true  Message should be sent by caller 
 
2399
    true  Message should be sent by caller
2358
2400
          (admin operation or network communication failed)
2359
2401
*/
2360
 
static bool mysql_admin_table(THD* thd, TableList* tables,
 
2402
static bool mysql_admin_table(Session* session, TableList* tables,
2361
2403
                              HA_CHECK_OPT* check_opt,
2362
2404
                              const char *operator_name,
2363
2405
                              thr_lock_type lock_type,
2364
2406
                              bool open_for_modify,
2365
2407
                              bool no_warnings_for_error,
2366
 
                              uint extra_open_options,
2367
 
                              int (*prepare_func)(THD *, TableList *,
 
2408
                              uint32_t extra_open_options,
 
2409
                              int (*prepare_func)(Session *, TableList *,
2368
2410
                                                  HA_CHECK_OPT *),
2369
 
                              int (handler::*operator_func)(THD *,
 
2411
                              int (handler::*operator_func)(Session *,
2370
2412
                                                            HA_CHECK_OPT *))
2371
2413
{
2372
2414
  TableList *table;
2373
 
  SELECT_LEX *select= &thd->lex->select_lex;
 
2415
  SELECT_LEX *select= &session->lex->select_lex;
2374
2416
  List<Item> field_list;
2375
2417
  Item *item;
2376
 
  Protocol *protocol= thd->protocol;
2377
 
  LEX *lex= thd->lex;
 
2418
  Protocol *protocol= session->protocol;
 
2419
  LEX *lex= session->lex;
2378
2420
  int result_code= 0;
2379
2421
  const CHARSET_INFO * const cs= system_charset_info;
2380
2422
 
2381
 
  if (end_active_trans(thd))
 
2423
  if (end_active_trans(session))
2382
2424
    return(1);
2383
2425
  field_list.push_back(item = new Item_empty_string("Table",
2384
2426
                                                    NAME_CHAR_LEN * 2,
2394
2436
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2395
2437
    return(true);
2396
2438
 
2397
 
  mysql_ha_rm_tables(thd, tables, false);
 
2439
  mysql_ha_rm_tables(session, tables, false);
2398
2440
 
2399
2441
  for (table= tables; table; table= table->next_local)
2400
2442
  {
2402
2444
    char* db = table->db;
2403
2445
    bool fatal_error=0;
2404
2446
 
2405
 
    strxmov(table_name, db, ".", table->table_name, NullS);
2406
 
    thd->open_options|= extra_open_options;
 
2447
    strxmov(table_name, db, ".", table->table_name, NULL);
 
2448
    session->open_options|= extra_open_options;
2407
2449
    table->lock_type= lock_type;
2408
2450
    /* open only one table from local list of command */
2409
2451
    {
2412
2454
      table->next_global= 0;
2413
2455
      save_next_local= table->next_local;
2414
2456
      table->next_local= 0;
2415
 
      select->table_list.first= (uchar*)table;
 
2457
      select->table_list.first= (unsigned char*)table;
2416
2458
      /*
2417
2459
        Time zone tables and SP tables can be add to lex->query_tables list,
2418
2460
        so it have to be prepared.
2422
2464
      lex->query_tables= table;
2423
2465
      lex->query_tables_last= &table->next_global;
2424
2466
      lex->query_tables_own_last= 0;
2425
 
      thd->no_warnings_for_error= no_warnings_for_error;
 
2467
      session->no_warnings_for_error= no_warnings_for_error;
2426
2468
 
2427
 
      open_and_lock_tables(thd, table);
2428
 
      thd->no_warnings_for_error= 0;
 
2469
      open_and_lock_tables(session, table);
 
2470
      session->no_warnings_for_error= 0;
2429
2471
      table->next_global= save_next_global;
2430
2472
      table->next_local= save_next_local;
2431
 
      thd->open_options&= ~extra_open_options;
 
2473
      session->open_options&= ~extra_open_options;
2432
2474
    }
2433
2475
 
2434
2476
    if (prepare_func)
2435
2477
    {
2436
 
      switch ((*prepare_func)(thd, table, check_opt)) {
 
2478
      switch ((*prepare_func)(session, table, check_opt)) {
2437
2479
      case  1:           // error, message written to net
2438
 
        ha_autocommit_or_rollback(thd, 1);
2439
 
        end_trans(thd, ROLLBACK);
2440
 
        close_thread_tables(thd);
 
2480
        ha_autocommit_or_rollback(session, 1);
 
2481
        end_trans(session, ROLLBACK);
 
2482
        close_thread_tables(session);
2441
2483
        continue;
2442
2484
      case -1:           // error, message could be written to net
2443
2485
        /* purecov: begin inspected */
2458
2500
    */
2459
2501
    if (!table->table)
2460
2502
    {
2461
 
      if (!thd->warn_list.elements)
2462
 
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2503
      if (!session->warn_list.elements)
 
2504
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
2463
2505
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2464
2506
      goto send_result;
2465
2507
    }
2468
2510
    {
2469
2511
      /* purecov: begin inspected */
2470
2512
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
2471
 
      uint length;
 
2513
      uint32_t length;
2472
2514
      protocol->prepare_for_resend();
2473
2515
      protocol->store(table_name, system_charset_info);
2474
2516
      protocol->store(operator_name, system_charset_info);
2476
2518
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2477
2519
                       table_name);
2478
2520
      protocol->store(buff, length, system_charset_info);
2479
 
      ha_autocommit_or_rollback(thd, 0);
2480
 
      end_trans(thd, COMMIT);
2481
 
      close_thread_tables(thd);
 
2521
      ha_autocommit_or_rollback(session, 0);
 
2522
      end_trans(session, COMMIT);
 
2523
      close_thread_tables(session);
2482
2524
      lex->reset_query_tables_list(false);
2483
2525
      table->table=0;                           // For query cache
2484
2526
      if (protocol->write())
2491
2533
    if (lock_type == TL_WRITE && table->table->s->version)
2492
2534
    {
2493
2535
      pthread_mutex_lock(&LOCK_open);
2494
 
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
 
2536
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2495
2537
                                              "Waiting to get writelock");
2496
 
      mysql_lock_abort(thd,table->table, true);
2497
 
      remove_table_from_cache(thd, table->table->s->db.str,
 
2538
      mysql_lock_abort(session,table->table, true);
 
2539
      remove_table_from_cache(session, table->table->s->db.str,
2498
2540
                              table->table->s->table_name.str,
2499
2541
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2500
2542
                              RTFC_CHECK_KILLED_FLAG);
2501
 
      thd->exit_cond(old_message);
2502
 
      if (thd->killed)
 
2543
      session->exit_cond(old_message);
 
2544
      if (session->killed)
2503
2545
        goto err;
2504
2546
      open_for_modify= 0;
2505
2547
    }
2525
2567
          (table->table->file->ha_check_for_upgrade(check_opt) ==
2526
2568
           HA_ADMIN_NEEDS_ALTER))
2527
2569
      {
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);
 
2570
        ha_autocommit_or_rollback(session, 1);
 
2571
        close_thread_tables(session);
 
2572
        tmp_disable_binlog(session); // binlogging is done by caller if wanted
 
2573
        result_code= mysql_recreate_table(session, table);
 
2574
        reenable_binlog(session);
2533
2575
        /*
2534
2576
          mysql_recreate_table() can push OK or ERROR.
2535
2577
          Clear 'OK' status. If there is an error, keep it:
2536
 
          we will store the error message in a result set row 
 
2578
          we will store the error message in a result set row
2537
2579
          and then clear.
2538
2580
        */
2539
 
        if (thd->main_da.is_ok())
2540
 
          thd->main_da.reset_diagnostics_area();
 
2581
        if (session->main_da.is_ok())
 
2582
          session->main_da.reset_diagnostics_area();
2541
2583
        goto send_result;
2542
2584
      }
2543
2585
    }
2544
2586
 
2545
 
    result_code = (table->table->file->*operator_func)(thd, check_opt);
 
2587
    result_code = (table->table->file->*operator_func)(session, check_opt);
2546
2588
 
2547
2589
send_result:
2548
2590
 
2549
2591
    lex->cleanup_after_one_table_open();
2550
 
    thd->clear_error();  // these errors shouldn't get client
 
2592
    session->clear_error();  // these errors shouldn't get client
2551
2593
    {
2552
 
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
2594
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2553
2595
      DRIZZLE_ERROR *err;
2554
2596
      while ((err= it++))
2555
2597
      {
2563
2605
        if (protocol->write())
2564
2606
          goto err;
2565
2607
      }
2566
 
      drizzle_reset_errors(thd, true);
 
2608
      drizzle_reset_errors(session, true);
2567
2609
    }
2568
2610
    protocol->prepare_for_resend();
2569
2611
    protocol->store(table_name, system_charset_info);
2575
2617
    case HA_ADMIN_NOT_IMPLEMENTED:
2576
2618
      {
2577
2619
        char buf[ERRMSGSIZE+20];
2578
 
        uint length=snprintf(buf, ERRMSGSIZE,
 
2620
        uint32_t length=snprintf(buf, ERRMSGSIZE,
2579
2621
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
2580
2622
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2581
2623
        protocol->store(buf, length, system_charset_info);
2585
2627
    case HA_ADMIN_NOT_BASE_TABLE:
2586
2628
      {
2587
2629
        char buf[ERRMSGSIZE+20];
2588
 
        uint length= snprintf(buf, ERRMSGSIZE,
 
2630
        uint32_t length= snprintf(buf, ERRMSGSIZE,
2589
2631
                              ER(ER_BAD_TABLE_ERROR), table_name);
2590
2632
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2591
2633
        protocol->store(buf, length, system_charset_info);
2635
2677
        "try with alter", so here we close the table, do an ALTER Table,
2636
2678
        reopen the table and do ha_innobase::analyze() on it.
2637
2679
      */
2638
 
      ha_autocommit_or_rollback(thd, 0);
2639
 
      close_thread_tables(thd);
 
2680
      ha_autocommit_or_rollback(session, 0);
 
2681
      close_thread_tables(session);
2640
2682
      TableList *save_next_local= table->next_local,
2641
2683
                 *save_next_global= table->next_global;
2642
2684
      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);
 
2685
      tmp_disable_binlog(session); // binlogging is done by caller if wanted
 
2686
      result_code= mysql_recreate_table(session, table);
 
2687
      reenable_binlog(session);
2646
2688
      /*
2647
2689
        mysql_recreate_table() can push OK or ERROR.
2648
2690
        Clear 'OK' status. If there is an error, keep it:
2649
 
        we will store the error message in a result set row 
 
2691
        we will store the error message in a result set row
2650
2692
        and then clear.
2651
2693
      */
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);
 
2694
      if (session->main_da.is_ok())
 
2695
        session->main_da.reset_diagnostics_area();
 
2696
      ha_autocommit_or_rollback(session, 0);
 
2697
      close_thread_tables(session);
2656
2698
      if (!result_code) // recreation went ok
2657
2699
      {
2658
 
        if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
2659
 
            ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
 
2700
        if ((table->table= open_ltable(session, table, lock_type, 0)) &&
 
2701
            ((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2660
2702
          result_code= 0; // analyze went ok
2661
2703
      }
2662
2704
      if (result_code) // either mysql_recreate_table or analyze failed
2663
2705
      {
2664
 
        assert(thd->is_error());
2665
 
        if (thd->is_error())
 
2706
        assert(session->is_error());
 
2707
        if (session->is_error())
2666
2708
        {
2667
 
          const char *err_msg= thd->main_da.message();
2668
 
          if (!thd->vio_ok())
 
2709
          const char *err_msg= session->main_da.message();
 
2710
          if (!session->vio_ok())
2669
2711
          {
2670
 
            sql_print_error(err_msg);
 
2712
            sql_print_error("%s",err_msg);
2671
2713
          }
2672
2714
          else
2673
2715
          {
2680
2722
            protocol->store(table_name, system_charset_info);
2681
2723
            protocol->store(operator_name, system_charset_info);
2682
2724
          }
2683
 
          thd->clear_error();
 
2725
          session->clear_error();
2684
2726
        }
2685
2727
      }
2686
2728
      result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
2700
2742
    case HA_ADMIN_NEEDS_ALTER:
2701
2743
    {
2702
2744
      char buf[ERRMSGSIZE];
2703
 
      uint length;
 
2745
      uint32_t length;
2704
2746
 
2705
2747
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2706
2748
      length=snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
2712
2754
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
2713
2755
      {
2714
2756
        char buf[ERRMSGSIZE+20];
2715
 
        uint length=snprintf(buf, ERRMSGSIZE,
 
2757
        uint32_t length=snprintf(buf, ERRMSGSIZE,
2716
2758
                             _("Unknown - internal error %d during operation"),
2717
2759
                             result_code);
2718
2760
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2732
2774
        else
2733
2775
        {
2734
2776
          pthread_mutex_lock(&LOCK_open);
2735
 
          remove_table_from_cache(thd, table->table->s->db.str,
 
2777
          remove_table_from_cache(session, table->table->s->db.str,
2736
2778
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
2737
2779
          pthread_mutex_unlock(&LOCK_open);
2738
2780
        }
2739
2781
      }
2740
2782
    }
2741
 
    ha_autocommit_or_rollback(thd, 0);
2742
 
    end_trans(thd, COMMIT);
2743
 
    close_thread_tables(thd);
 
2783
    ha_autocommit_or_rollback(session, 0);
 
2784
    end_trans(session, COMMIT);
 
2785
    close_thread_tables(session);
2744
2786
    table->table=0;                             // For query cache
2745
2787
    if (protocol->write())
2746
2788
      goto err;
2747
2789
  }
2748
2790
 
2749
 
  my_eof(thd);
 
2791
  my_eof(session);
2750
2792
  return(false);
2751
2793
 
2752
2794
err:
2753
 
  ha_autocommit_or_rollback(thd, 1);
2754
 
  end_trans(thd, ROLLBACK);
2755
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
2795
  ha_autocommit_or_rollback(session, 1);
 
2796
  end_trans(session, ROLLBACK);
 
2797
  close_thread_tables(session);                 // Shouldn't be needed
2756
2798
  if (table)
2757
2799
    table->table=0;
2758
2800
  return(true);
2759
2801
}
2760
2802
 
2761
2803
 
2762
 
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2804
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2763
2805
{
2764
 
  return(mysql_admin_table(thd, tables, check_opt,
 
2806
  return(mysql_admin_table(session, tables, check_opt,
2765
2807
                                "repair", TL_WRITE, 1,
2766
2808
                                test(check_opt->sql_flags & TT_USEFRM),
2767
2809
                                HA_OPEN_FOR_REPAIR,
2770
2812
}
2771
2813
 
2772
2814
 
2773
 
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
2815
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2774
2816
{
2775
 
  return(mysql_admin_table(thd, tables, check_opt,
 
2817
  return(mysql_admin_table(session, tables, check_opt,
2776
2818
                                "optimize", TL_WRITE, 1,0,0,0,
2777
2819
                                &handler::ha_optimize));
2778
2820
}
2783
2825
 
2784
2826
  SYNOPSIS
2785
2827
    mysql_assign_to_keycache()
2786
 
    thd         Thread object
 
2828
    session             Thread object
2787
2829
    tables      Table list (one table only)
2788
2830
 
2789
2831
  RETURN VALUES
2791
2833
   true  error
2792
2834
*/
2793
2835
 
2794
 
bool mysql_assign_to_keycache(THD* thd, TableList* tables,
 
2836
bool mysql_assign_to_keycache(Session* session, TableList* tables,
2795
2837
                             LEX_STRING *key_cache_name)
2796
2838
{
2797
2839
  HA_CHECK_OPT check_opt;
2807
2849
  }
2808
2850
  pthread_mutex_unlock(&LOCK_global_system_variables);
2809
2851
  check_opt.key_cache= key_cache;
2810
 
  return(mysql_admin_table(thd, tables, &check_opt,
 
2852
  return(mysql_admin_table(session, tables, &check_opt,
2811
2853
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
2812
2854
                                0, 0, &handler::assign_to_keycache));
2813
2855
}
2818
2860
 
2819
2861
  SYNOPSIS
2820
2862
    reassign_keycache_tables()
2821
 
    thd         Thread object
 
2863
    session             Thread object
2822
2864
    src_cache   Reference to the key cache to clean up
2823
2865
    dest_cache  New key cache
2824
2866
 
2838
2880
    0     ok
2839
2881
*/
2840
2882
 
2841
 
int reassign_keycache_tables(THD *thd __attribute__((unused)),
 
2883
int reassign_keycache_tables(Session *session __attribute__((unused)),
2842
2884
                             KEY_CACHE *src_cache,
2843
2885
                             KEY_CACHE *dst_cache)
2844
2886
{
2853
2895
/**
2854
2896
  @brief          Create frm file based on I_S table
2855
2897
 
2856
 
  @param[in]      thd                      thread handler
2857
 
  @param[in]      schema_table             I_S table           
 
2898
  @param[in]      session                      thread handler
 
2899
  @param[in]      schema_table             I_S table
2858
2900
  @param[in]      dst_path                 path where frm should be created
2859
2901
  @param[in]      create_info              Create info
2860
2902
 
2862
2904
    @retval       0                        success
2863
2905
    @retval       1                        error
2864
2906
*/
2865
 
bool mysql_create_like_schema_frm(THD* thd, TableList* schema_table,
 
2907
bool mysql_create_like_schema_frm(Session* session, TableList* schema_table,
2866
2908
                                  char *dst_path, HA_CREATE_INFO *create_info)
2867
2909
{
2868
2910
  HA_CREATE_INFO local_create_info;
2869
2911
  Alter_info alter_info;
2870
2912
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
2871
 
  uint keys= schema_table->table->s->keys;
2872
 
  uint db_options= 0;
 
2913
  uint32_t keys= schema_table->table->s->keys;
 
2914
  uint32_t db_options= 0;
2873
2915
 
2874
2916
  memset(&local_create_info, 0, sizeof(local_create_info));
2875
2917
  local_create_info.db_type= schema_table->table->s->db_type();
2877
2919
  local_create_info.default_table_charset=default_charset_info;
2878
2920
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2879
2921
  schema_table->table->use_all_columns();
2880
 
  if (mysql_prepare_alter_table(thd, schema_table->table,
 
2922
  if (mysql_prepare_alter_table(session, schema_table->table,
2881
2923
                                &local_create_info, &alter_info))
2882
2924
    return(1);
2883
 
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
 
2925
  if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2884
2926
                                 tmp_table, &db_options,
2885
2927
                                 schema_table->table->file,
2886
2928
                                 &schema_table->table->s->key_info, &keys, 0))
2887
2929
    return(1);
2888
2930
  local_create_info.max_rows= 0;
2889
 
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
 
2931
  if (mysql_create_frm(session, dst_path, NULL, NULL,
2890
2932
                       &local_create_info, alter_info.create_list,
2891
2933
                       keys, schema_table->table->s->key_info,
2892
2934
                       schema_table->table->file))
2900
2942
 
2901
2943
  SYNOPSIS
2902
2944
    mysql_create_like_table()
2903
 
    thd         Thread object
 
2945
    session             Thread object
2904
2946
    table       Table list element for target table
2905
2947
    src_table   Table list element for source table
2906
2948
    create_info Create info
2910
2952
    true  error
2911
2953
*/
2912
2954
 
2913
 
bool mysql_create_like_table(THD* thd, TableList* table, TableList* src_table,
 
2955
bool mysql_create_like_table(Session* session, TableList* table, TableList* src_table,
2914
2956
                             HA_CREATE_INFO *create_info)
2915
2957
{
2916
2958
  Table *name_lock= 0;
2917
2959
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
2918
 
  uint dst_path_length;
 
2960
  uint32_t dst_path_length;
2919
2961
  char *db= table->db;
2920
2962
  char *table_name= table->table_name;
2921
2963
  int  err;
2922
2964
  bool res= true;
2923
 
  uint not_used;
 
2965
  uint32_t not_used;
2924
2966
 
2925
2967
  /*
2926
2968
    By opening source table we guarantee that it exists and no concurrent
2931
2973
    we ensure that our statement is properly isolated from all concurrent
2932
2974
    operations which matter.
2933
2975
  */
2934
 
  if (open_tables(thd, &src_table, &not_used, 0))
 
2976
  if (open_tables(session, &src_table, &not_used, 0))
2935
2977
    return(true);
2936
2978
 
2937
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
 
2979
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
2938
2980
 
2939
 
  /* 
 
2981
  /*
2940
2982
    Check that destination tables does not exist. Note that its name
2941
2983
    was already checked when it was added to the table list.
2942
2984
  */
2943
2985
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2944
2986
  {
2945
 
    if (find_temporary_table(thd, db, table_name))
 
2987
    if (find_temporary_table(session, db, table_name))
2946
2988
      goto table_exists;
2947
 
    dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
 
2989
    dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2948
2990
    create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2949
2991
  }
2950
2992
  else
2951
2993
  {
2952
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
2994
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2953
2995
      goto err;
2954
2996
    if (!name_lock)
2955
2997
      goto table_exists;
2972
3014
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2973
3015
    during the call to ha_create_table(). See bug #28614 for more info.
2974
3016
  */
2975
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
3017
  pthread_mutex_lock(&LOCK_open);
2976
3018
  if (src_table->schema_table)
2977
3019
  {
2978
 
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
 
3020
    if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
2979
3021
    {
2980
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
3022
      pthread_mutex_unlock(&LOCK_open);
2981
3023
      goto err;
2982
3024
    }
2983
3025
  }
2987
3029
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2988
3030
    else
2989
3031
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2990
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3032
    pthread_mutex_unlock(&LOCK_open);
2991
3033
    goto err;
2992
3034
  }
2993
3035
 
2997
3039
    and temporary tables).
2998
3040
  */
2999
3041
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
3000
 
  if (thd->variables.keep_files_on_create)
 
3042
  if (session->variables.keep_files_on_create)
3001
3043
    create_info->options|= HA_CREATE_KEEP_FILES;
3002
 
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
3003
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3044
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
 
3045
  pthread_mutex_unlock(&LOCK_open);
3004
3046
 
3005
3047
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3006
3048
  {
3007
 
    if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
 
3049
    if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3008
3050
                                     OTM_OPEN))
3009
3051
    {
3010
3052
      (void) rm_temporary_table(create_info->db_type,
3011
 
                                dst_path, false); /* purecov: inspected */
 
3053
                                dst_path);
3012
3054
      goto err;     /* purecov: inspected */
3013
3055
    }
3014
3056
  }
3022
3064
  /*
3023
3065
    We have to write the query before we unlock the tables.
3024
3066
  */
3025
 
  if (thd->current_stmt_binlog_row_based)
3026
3067
  {
3027
3068
    /*
3028
3069
       Since temporary tables are not replicated under row-based
3055
3096
          of this function.
3056
3097
        */
3057
3098
        table->table= name_lock;
3058
 
        VOID(pthread_mutex_lock(&LOCK_open));
3059
 
        if (reopen_name_locked_table(thd, table, false))
 
3099
        pthread_mutex_lock(&LOCK_open);
 
3100
        if (reopen_name_locked_table(session, table, false))
3060
3101
        {
3061
 
          VOID(pthread_mutex_unlock(&LOCK_open));
 
3102
          pthread_mutex_unlock(&LOCK_open);
3062
3103
          goto err;
3063
3104
        }
3064
 
        VOID(pthread_mutex_unlock(&LOCK_open));
 
3105
        pthread_mutex_unlock(&LOCK_open);
3065
3106
 
3066
 
        int result= store_create_info(thd, table, &query,
 
3107
        int result= store_create_info(session, table, &query,
3067
3108
                                               create_info);
3068
3109
 
3069
3110
        assert(result == 0); // store_create_info() always return 0
3070
 
        write_bin_log(thd, true, query.ptr(), query.length());
 
3111
        write_bin_log(session, true, query.ptr(), query.length());
3071
3112
      }
3072
3113
      else                                      // Case 1
3073
 
        write_bin_log(thd, true, thd->query, thd->query_length);
 
3114
        write_bin_log(session, true, session->query, session->query_length);
3074
3115
    }
3075
3116
    /*
3076
3117
      Case 3 and 4 does nothing under RBR
3077
3118
    */
3078
3119
  }
3079
 
  else
3080
 
    write_bin_log(thd, true, thd->query, thd->query_length);
3081
3120
 
3082
3121
  res= false;
3083
3122
  goto err;
3088
3127
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
3089
3128
    snprintf(warn_buff, sizeof(warn_buff),
3090
3129
             ER(ER_TABLE_EXISTS_ERROR), table_name);
3091
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3130
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3092
3131
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3093
3132
    res= false;
3094
3133
  }
3099
3138
  if (name_lock)
3100
3139
  {
3101
3140
    pthread_mutex_lock(&LOCK_open);
3102
 
    unlink_open_table(thd, name_lock, false);
 
3141
    unlink_open_table(session, name_lock, false);
3103
3142
    pthread_mutex_unlock(&LOCK_open);
3104
3143
  }
3105
3144
  return(res);
3106
3145
}
3107
3146
 
3108
3147
 
3109
 
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
 
3148
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3110
3149
{
3111
3150
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3112
3151
 
3113
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3152
  return(mysql_admin_table(session, tables, check_opt,
3114
3153
                                "analyze", lock_type, 1, 0, 0, 0,
3115
3154
                                &handler::ha_analyze));
3116
3155
}
3117
3156
 
3118
3157
 
3119
 
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
 
3158
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3120
3159
{
3121
3160
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3122
3161
 
3123
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3162
  return(mysql_admin_table(session, tables, check_opt,
3124
3163
                                "check", lock_type,
3125
3164
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
3126
3165
                                &handler::ha_check));
3129
3168
 
3130
3169
/* table_list should contain just one table */
3131
3170
static int
3132
 
mysql_discard_or_import_tablespace(THD *thd,
 
3171
mysql_discard_or_import_tablespace(Session *session,
3133
3172
                                   TableList *table_list,
3134
3173
                                   enum tablespace_op_type tablespace_op)
3135
3174
{
3142
3181
    ALTER Table
3143
3182
  */
3144
3183
 
3145
 
  thd_proc_info(thd, "discard_or_import_tablespace");
 
3184
  session->set_proc_info("discard_or_import_tablespace");
3146
3185
 
3147
3186
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3148
3187
 
3150
3189
   We set this flag so that ha_innobase::open and ::external_lock() do
3151
3190
   not complain when we lock the table
3152
3191
 */
3153
 
  thd->tablespace_op= true;
3154
 
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
 
3192
  session->tablespace_op= true;
 
3193
  if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3155
3194
  {
3156
 
    thd->tablespace_op=false;
 
3195
    session->tablespace_op=false;
3157
3196
    return(-1);
3158
3197
  }
3159
3198
 
3160
3199
  error= table->file->ha_discard_or_import_tablespace(discard);
3161
3200
 
3162
 
  thd_proc_info(thd, "end");
 
3201
  session->set_proc_info("end");
3163
3202
 
3164
3203
  if (error)
3165
3204
    goto err;
3166
3205
 
3167
3206
  /* The ALTER Table is always in its own transaction */
3168
 
  error = ha_autocommit_or_rollback(thd, 0);
3169
 
  if (end_active_trans(thd))
 
3207
  error = ha_autocommit_or_rollback(session, 0);
 
3208
  if (end_active_trans(session))
3170
3209
    error=1;
3171
3210
  if (error)
3172
3211
    goto err;
3173
 
  write_bin_log(thd, false, thd->query, thd->query_length);
 
3212
  write_bin_log(session, false, session->query, session->query_length);
3174
3213
 
3175
3214
err:
3176
 
  ha_autocommit_or_rollback(thd, error);
3177
 
  thd->tablespace_op=false;
3178
 
  
 
3215
  ha_autocommit_or_rollback(session, error);
 
3216
  session->tablespace_op=false;
 
3217
 
3179
3218
  if (error == 0)
3180
3219
  {
3181
 
    my_ok(thd);
 
3220
    my_ok(session);
3182
3221
    return(0);
3183
3222
  }
3184
3223
 
3185
3224
  table->file->print_error(error, MYF(0));
3186
 
    
 
3225
 
3187
3226
  return(-1);
3188
3227
}
3189
3228
 
3193
3232
 
3194
3233
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
3195
3234
{
3196
 
  uint flags= alter_info->flags;
 
3235
  uint32_t flags= alter_info->flags;
3197
3236
 
3198
3237
  if (ALTER_ADD_COLUMN & flags)
3199
3238
    *alter_flags|= HA_ADD_COLUMN;
3223
3262
 
3224
3263
 
3225
3264
/**
3226
 
   @param       thd                Thread
 
3265
   @param       session                Thread
3227
3266
   @param       table              The original table.
3228
3267
   @param       alter_info         Alter options, fields and keys for the new
3229
3268
                                   table.
3255
3294
 
3256
3295
static
3257
3296
bool
3258
 
compare_tables(THD *thd,
 
3297
compare_tables(Session *session,
3259
3298
               Table *table,
3260
3299
               Alter_info *alter_info,
3261
3300
                           HA_CREATE_INFO *create_info,
3262
 
               uint order_num,
 
3301
               uint32_t order_num,
3263
3302
               HA_ALTER_FLAGS *alter_flags,
3264
3303
               HA_ALTER_INFO *ha_alter_info,
3265
 
               uint *table_changes)
 
3304
               uint32_t *table_changes)
3266
3305
{
3267
3306
  Field **f_ptr, *field;
3268
 
  uint table_changes_local= 0;
 
3307
  uint32_t table_changes_local= 0;
3269
3308
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
3270
3309
  Create_field *new_field;
3271
3310
  KEY_PART_INFO *key_part;
3272
3311
  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
3312
 
3279
3313
  {
3280
3314
    /*
3292
3326
      to evaluate possibility of fast ALTER Table, and then
3293
3327
      destroy the copy.
3294
3328
    */
3295
 
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
3296
 
    THD *thd= table->in_use;
3297
 
    uint db_options= 0; /* not used */
 
3329
    Alter_info tmp_alter_info(*alter_info, session->mem_root);
 
3330
    Session *session= table->in_use;
 
3331
    uint32_t db_options= 0; /* not used */
3298
3332
    /* Create the prepared information. */
3299
 
    if (mysql_prepare_create_table(thd, create_info,
 
3333
    if (mysql_prepare_create_table(session, create_info,
3300
3334
                                   &tmp_alter_info,
3301
3335
                                   (table->s->tmp_table != NO_TMP_TABLE),
3302
3336
                                   &db_options,
3307
3341
      return(true);
3308
3342
    /* Allocate result buffers. */
3309
3343
    if (! (ha_alter_info->index_drop_buffer=
3310
 
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
 
3344
           (uint*) session->alloc(sizeof(uint) * table->s->keys)) ||
3311
3345
        ! (ha_alter_info->index_add_buffer=
3312
 
           (uint*) thd->alloc(sizeof(uint) *
 
3346
           (uint*) session->alloc(sizeof(uint) *
3313
3347
                              tmp_alter_info.key_list.elements)))
3314
3348
      return(true);
3315
3349
  }
3355
3389
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3356
3390
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3357
3391
      order_num ||
3358
 
      !table->s->mysql_version ||
3359
 
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
 
3392
      !table->s->mysql_version)
3360
3393
  {
3361
3394
    *table_changes= IS_EQUAL_NO;
3362
3395
    /*
3378
3411
    /* TODO check for ADD/DROP FOREIGN KEY */
3379
3412
    if (alter_info->flags & ALTER_FOREIGN_KEY)
3380
3413
      *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
3414
  }
3385
3415
  /*
3386
3416
    Go through fields and check if the original ones are compatible
3407
3437
      if (!(table_changes_local= field->is_equal(new_field)))
3408
3438
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3409
3439
 
 
3440
      /*
 
3441
        Check if the altered column is a stored virtual field.
 
3442
        TODO: Mark such a column with an alter flag only if
 
3443
        the expression functions are not equal.
 
3444
      */
 
3445
      if (field->is_stored && field->vcol_info)
 
3446
        *alter_flags|= HA_ALTER_STORED_VCOL;
 
3447
 
3410
3448
      /* Check if field was renamed */
3411
3449
      field->flags&= ~FIELD_IS_RENAMED;
3412
3450
      if (my_strcasecmp(system_charset_info,
3472
3510
      if (table_key->flags & HA_NOSAME)
3473
3511
      {
3474
3512
        /* Unique key. Check for "PRIMARY". */
3475
 
        if (! my_strcasecmp(system_charset_info,
3476
 
                            table_key->name, primary_key_name))
 
3513
        if (is_primary_key(table_key))
3477
3514
          *alter_flags|= HA_DROP_PK_INDEX;
3478
3515
        else
3479
3516
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
3493
3530
      if (table_key->flags & HA_NOSAME)
3494
3531
      {
3495
3532
        // Unique key. Check for "PRIMARY".
3496
 
        if (! my_strcasecmp(system_charset_info,
3497
 
                            table_key->name, primary_key_name))
 
3533
        if (is_primary_key(table_key))
3498
3534
          *alter_flags|= HA_ALTER_PK_INDEX;
3499
3535
        else
3500
3536
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3523
3559
        if (table_key->flags & HA_NOSAME)
3524
3560
        {
3525
3561
          /* Unique key. Check for "PRIMARY" */
3526
 
          if (! my_strcasecmp(system_charset_info,
3527
 
                              table_key->name, primary_key_name))
 
3562
          if (is_primary_key(table_key))
3528
3563
            *alter_flags|= HA_ALTER_PK_INDEX;
3529
3564
          else
3530
3565
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3586
3621
      if (new_key->flags & HA_NOSAME)
3587
3622
      {
3588
3623
        /* Unique key. Check for "PRIMARY" */
3589
 
        if (! my_strcasecmp(system_charset_info,
3590
 
                            new_key->name, primary_key_name))
 
3624
        if (is_primary_key(new_key))
3591
3625
          *alter_flags|= HA_ADD_PK_INDEX;
3592
3626
        else
3593
3627
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
3636
3670
 
3637
3671
  if (error == HA_ERR_WRONG_COMMAND)
3638
3672
  {
3639
 
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3673
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3640
3674
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3641
3675
                        table->s->table_name.str);
3642
3676
    error= 0;
3646
3680
  return(error);
3647
3681
}
3648
3682
 
3649
 
int create_temporary_table(THD *thd,
 
3683
int create_temporary_table(Session *session,
3650
3684
                           Table *table,
3651
3685
                           char *new_db,
3652
3686
                           char *tmp_name,
3688
3722
    if (create_info->index_file_name)
3689
3723
    {
3690
3724
      /* Fix index_file_name to have 'tmp_name' as basename */
3691
 
      stpcpy(index_file, tmp_name);
 
3725
      strcpy(index_file, tmp_name);
3692
3726
      create_info->index_file_name=fn_same(index_file,
3693
3727
                                           create_info->index_file_name,
3694
3728
                                           1);
3696
3730
    if (create_info->data_file_name)
3697
3731
    {
3698
3732
      /* Fix data_file_name to have 'tmp_name' as basename */
3699
 
      stpcpy(data_file, tmp_name);
 
3733
      strcpy(data_file, tmp_name);
3700
3734
      create_info->data_file_name=fn_same(data_file,
3701
3735
                                          create_info->data_file_name,
3702
3736
                                          1);
3707
3741
 
3708
3742
  /*
3709
3743
    Create a table with a temporary name.
3710
 
    With create_info->frm_only == 1 this creates a .frm file only.
3711
3744
    We don't log the statement, it will be logged later.
3712
3745
  */
3713
 
  tmp_disable_binlog(thd);
3714
 
  error= mysql_create_table(thd, new_db, tmp_name,
 
3746
  tmp_disable_binlog(session);
 
3747
  error= mysql_create_table(session, new_db, tmp_name,
3715
3748
                            create_info, alter_info, 1, 0);
3716
 
  reenable_binlog(thd);
 
3749
  reenable_binlog(session);
3717
3750
 
3718
3751
  return(error);
3719
3752
}
3724
3757
 
3725
3758
  SYNOPSIS
3726
3759
    create_altered_table()
3727
 
      thd              Thread handle
 
3760
      session              Thread handle
3728
3761
      table            The original table
3729
3762
      create_info      Information from the parsing phase about new
3730
3763
                       table properties.
3738
3771
    The temporary table is created without storing it in any storage engine
3739
3772
    and is opened only to get the table struct and frm file reference.
3740
3773
*/
3741
 
Table *create_altered_table(THD *thd,
 
3774
Table *create_altered_table(Session *session,
3742
3775
                            Table *table,
3743
3776
                            char *new_db,
3744
3777
                            HA_CREATE_INFO *create_info,
3751
3784
  char tmp_name[80];
3752
3785
  char path[FN_REFLEN];
3753
3786
 
3754
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3755
 
           tmp_file_prefix, current_pid, thd->thread_id);
 
3787
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
 
3788
           TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3756
3789
  /* Safety fix for InnoDB */
3757
3790
  if (lower_case_table_names)
3758
3791
    my_casedn_str(files_charset_info, tmp_name);
3759
3792
  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,
 
3793
 
 
3794
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
3762
3795
                                     &altered_create_info,
3763
3796
                                     alter_info, db_change)))
3764
3797
  {
3767
3800
 
3768
3801
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
3769
3802
                       FN_IS_TMP);
3770
 
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
 
3803
  altered_table= open_temporary_table(session, path, new_db, tmp_name, 1,
3771
3804
                                      OTM_ALTER);
3772
3805
  return(altered_table);
3773
3806
 
3780
3813
 
3781
3814
  SYNOPSIS
3782
3815
    mysql_fast_or_online_alter_table()
3783
 
      thd              Thread handle
 
3816
      session              Thread handle
3784
3817
      table            The original table
3785
3818
      altered_table    A temporary table showing how we will change table
3786
3819
      create_info      Information from the parsing phase about new
3800
3833
    operation directly, on-line without mysql having to copy
3801
3834
    the table.
3802
3835
*/
3803
 
int mysql_fast_or_online_alter_table(THD *thd,
 
3836
int mysql_fast_or_online_alter_table(Session *session,
3804
3837
                                     Table *table,
3805
3838
                                     Table *altered_table,
3806
3839
                                     HA_CREATE_INFO *create_info,
3817
3850
   /*
3818
3851
      Tell the handler to prepare for the online alter
3819
3852
    */
3820
 
    if ((error= table->file->alter_table_phase1(thd,
 
3853
    if ((error= table->file->alter_table_phase1(session,
3821
3854
                                                altered_table,
3822
3855
                                                create_info,
3823
3856
                                                alter_info,
3828
3861
 
3829
3862
    /*
3830
3863
       Tell the storage engine to perform the online alter table
3831
 
       TODO: 
 
3864
       TODO:
3832
3865
       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
3833
3866
       we need to wrap the next call with a DDL lock.
3834
3867
     */
3835
 
    if ((error= table->file->alter_table_phase2(thd,
 
3868
    if ((error= table->file->alter_table_phase2(session,
3836
3869
                                                altered_table,
3837
3870
                                                create_info,
3838
3871
                                                alter_info,
3845
3878
    The final .frm file is already created as a temporary file
3846
3879
    and will be renamed to the original table name.
3847
3880
  */
3848
 
  VOID(pthread_mutex_lock(&LOCK_open));
3849
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
3881
  pthread_mutex_lock(&LOCK_open);
 
3882
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3850
3883
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3851
3884
                          keys_onoff);
3852
 
  close_data_files_and_morph_locks(thd,
 
3885
  close_data_files_and_morph_locks(session,
3853
3886
                                   table->pos_in_table_list->db,
3854
3887
                                   table->pos_in_table_list->table_name);
3855
3888
  if (mysql_rename_table(NULL,
3859
3892
                         table->s->table_name.str, FN_FROM_IS_TMP))
3860
3893
  {
3861
3894
    error= 1;
3862
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3895
    pthread_mutex_unlock(&LOCK_open);
3863
3896
    goto err;
3864
3897
  }
3865
3898
  broadcast_refresh();
3866
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3899
  pthread_mutex_unlock(&LOCK_open);
3867
3900
 
3868
3901
  /*
3869
3902
    The ALTER Table is always in its own transaction.
3871
3904
    wait_if_global_read_lock(), which could create a deadlock if called
3872
3905
    with LOCK_open.
3873
3906
  */
3874
 
  error= ha_autocommit_or_rollback(thd, 0);
 
3907
  error= ha_autocommit_or_rollback(session, 0);
3875
3908
 
3876
 
  if (ha_commit(thd))
 
3909
  if (ha_commit(session))
3877
3910
    error=1;
3878
3911
  if (error)
3879
3912
    goto err;
3880
3913
  if (online)
3881
3914
  {
3882
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3915
    pthread_mutex_lock(&LOCK_open);
3883
3916
    if (reopen_table(table))
3884
3917
    {
3885
3918
      error= -1;
3886
3919
      goto err;
3887
3920
    }
3888
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3921
    pthread_mutex_unlock(&LOCK_open);
3889
3922
    t_table= table;
3890
3923
 
3891
3924
   /*
3892
3925
      Tell the handler that the changed frm is on disk and table
3893
3926
      has been re-opened
3894
3927
   */
3895
 
    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
 
3928
    if ((error= t_table->file->alter_table_phase3(session, t_table)))
3896
3929
    {
3897
3930
      goto err;
3898
3931
    }
3904
3937
    */
3905
3938
    assert(t_table == table);
3906
3939
    table->open_placeholder= 1;
3907
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3940
    pthread_mutex_lock(&LOCK_open);
3908
3941
    close_handle_and_leave_table_as_lock(table);
3909
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3942
    pthread_mutex_unlock(&LOCK_open);
3910
3943
  }
3911
3944
 
3912
3945
 err:
3931
3964
  instructions that require change in table data, not only in
3932
3965
  table definition or indexes.
3933
3966
 
3934
 
  @param[in,out]  thd         thread handle. Used as a memory pool
 
3967
  @param[in,out]  session         thread handle. Used as a memory pool
3935
3968
                              and source of environment information.
3936
3969
  @param[in]      table       the source table, open and locked
3937
3970
                              Used as an interface to the storage engine
3958
3991
*/
3959
3992
 
3960
3993
static bool
3961
 
mysql_prepare_alter_table(THD *thd, Table *table,
 
3994
mysql_prepare_alter_table(Session *session, Table *table,
3962
3995
                          HA_CREATE_INFO *create_info,
3963
3996
                          Alter_info *alter_info)
3964
3997
{
3973
4006
  List_iterator<Create_field> find_it(new_create_list);
3974
4007
  List_iterator<Create_field> field_it(new_create_list);
3975
4008
  List<Key_part_spec> key_parts;
3976
 
  uint db_create_options= (table->s->db_create_options
 
4009
  uint32_t db_create_options= (table->s->db_create_options
3977
4010
                           & ~(HA_OPTION_PACK_RECORD));
3978
 
  uint used_fields= create_info->used_fields;
 
4011
  uint32_t used_fields= create_info->used_fields;
3979
4012
  KEY *key_info=table->key_info;
3980
4013
  bool rc= true;
3981
4014
 
4000
4033
  }
4001
4034
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
4002
4035
    create_info->key_block_size= table->s->key_block_size;
4003
 
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
4004
 
    create_info->transactional= table->s->transactional;
4005
4036
 
4006
4037
  restore_record(table, s->default_values);     // Empty record for DEFAULT
4007
4038
  Create_field *def;
4046
4077
    if (def)
4047
4078
    {                                           // Field is changed
4048
4079
      def->field=field;
 
4080
      if (field->is_stored != def->is_stored)
 
4081
      {
 
4082
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
4083
                 MYF(0),
 
4084
                 "Changing the STORED status");
 
4085
        goto err;
 
4086
      }
4049
4087
      if (!def->after)
4050
4088
        {
4051
4089
        new_create_list.push_back(def);
4097
4135
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4098
4136
      flag to allow ALTER Table only if the table to be altered is empty.
4099
4137
      */
4100
 
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
 
4138
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4101
4139
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4102
4140
         !alter_info->datetime_field &&
4103
4141
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4104
 
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
 
4142
         session->variables.sql_mode & MODE_NO_ZERO_DATE)
4105
4143
    {
4106
4144
        alter_info->datetime_field= def;
4107
4145
        alter_info->error_if_not_empty= true;
4137
4175
      */
4138
4176
      if (alter_info->build_method == HA_BUILD_ONLINE)
4139
4177
      {
4140
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4178
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4141
4179
        goto err;
4142
4180
      }
4143
4181
      alter_info->build_method= HA_BUILD_OFFLINE;
4161
4199
    for which some fields exists.
4162
4200
    */
4163
4201
 
4164
 
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
 
4202
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
4165
4203
    {
4166
4204
    char *key_name= key_info->name;
4167
4205
    Alter_drop *drop;
4180
4218
 
4181
4219
    KEY_PART_INFO *key_part= key_info->key_part;
4182
4220
    key_parts.empty();
4183
 
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
 
4221
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
4184
4222
    {
4185
4223
      if (!key_part->field)
4186
4224
        continue;                               // Wrong field (from UNIREG)
4201
4239
      }
4202
4240
      if (!cfield)
4203
4241
        continue;                               // Field is removed
4204
 
      uint key_part_length=key_part->length;
 
4242
      uint32_t key_part_length=key_part->length;
4205
4243
      if (cfield->field)                        // Not new field
4206
4244
      {
4207
4245
        /*
4244
4282
 
4245
4283
      if (key_info->flags & HA_NOSAME)
4246
4284
      {
4247
 
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
 
4285
        if (is_primary_key_name(key_name))
4248
4286
          key_type= Key::PRIMARY;
4249
4287
        else
4250
4288
          key_type= Key::UNIQUE;
4263
4301
    Key *key;
4264
4302
    while ((key=key_it++))                      // Add new keys
4265
4303
    {
 
4304
      if (key->type == Key::FOREIGN_KEY &&
 
4305
          ((Foreign_key *)key)->validate(new_create_list))
 
4306
        goto err;
4266
4307
      if (key->type != Key::FOREIGN_KEY)
4267
4308
        new_key_list.push_back(key);
4268
 
      if (key->name.str &&
4269
 
          !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
 
4309
      if (key->name.str && is_primary_key_name(key->name.str))
4270
4310
      {
4271
4311
        my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
4272
4312
        goto err;
4323
4363
 
4324
4364
  SYNOPSIS
4325
4365
    mysql_alter_table()
4326
 
      thd              Thread handle
 
4366
      session              Thread handle
4327
4367
      new_db           If there is a RENAME clause
4328
4368
      new_name         If there is a RENAME clause
4329
4369
      create_info      Information from the parsing phase about new
4360
4400
    true   Error
4361
4401
*/
4362
4402
 
4363
 
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 
4403
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4364
4404
                       HA_CREATE_INFO *create_info,
4365
4405
                       TableList *table_list,
4366
4406
                       Alter_info *alter_info,
4367
 
                       uint order_num, order_st *order, bool ignore)
 
4407
                       uint32_t order_num, order_st *order, bool ignore)
4368
4408
{
4369
4409
  Table *table, *new_table=0, *name_lock= 0;;
 
4410
  std::string new_name_str;
4370
4411
  int error= 0;
4371
4412
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4372
4413
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4373
4414
  char path[FN_REFLEN];
4374
4415
  ha_rows copied= 0,deleted= 0;
4375
4416
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4376
 
  legacy_db_type table_type;
 
4417
 
 
4418
  new_name_buff[0]= '\0';
4377
4419
 
4378
4420
  if (table_list && table_list->schema_table)
4379
4421
  {
4380
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
4422
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4381
4423
    return(true);
4382
4424
  }
4383
4425
 
4386
4428
    to simplify further comparisons: we want to see if it's a RENAME
4387
4429
    later just by comparing the pointers, avoiding the need for strcmp.
4388
4430
  */
4389
 
  thd_proc_info(thd, "init");
 
4431
  session->set_proc_info("init");
4390
4432
  table_name=table_list->table_name;
4391
4433
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4392
4434
  db=table_list->db;
4394
4436
    new_db= db;
4395
4437
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
4396
4438
 
4397
 
  mysql_ha_rm_tables(thd, table_list, false);
 
4439
  mysql_ha_rm_tables(session, table_list, false);
4398
4440
 
4399
4441
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4400
4442
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4401
4443
    /* Conditionally writes to binlog. */
4402
 
    return(mysql_discard_or_import_tablespace(thd,table_list,
 
4444
    return(mysql_discard_or_import_tablespace(session,table_list,
4403
4445
                                              alter_info->tablespace_op));
4404
 
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
4405
 
           "/", table_name, reg_ext, NullS);
4406
 
  (void) unpack_filename(new_name_buff, new_name_buff);
 
4446
  std::ostringstream oss;
 
4447
  oss << drizzle_data_home << "/" << db << "/" << table_name << reg_ext;
 
4448
 
 
4449
  (void) unpack_filename(new_name_buff, oss.str().c_str());
4407
4450
  /*
4408
4451
    If this is just a rename of a view, short cut to the
4409
4452
    following scenario: 1) lock LOCK_open 2) do a RENAME
4417
4460
    into the main table list, like open_tables does).
4418
4461
    This code is wrong and will be removed, please do not copy.
4419
4462
  */
4420
 
  (void)mysql_frm_type(thd, new_name_buff, &table_type);
4421
4463
 
4422
 
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
 
4464
  if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4423
4465
    return(true);
4424
4466
  table->use_all_columns();
4425
4467
 
4426
4468
  /* Check that we are not trying to rename to an existing table */
4427
4469
  if (new_name)
4428
4470
  {
4429
 
    stpcpy(new_name_buff,new_name);
4430
 
    stpcpy(new_alias= new_alias_buff, new_name);
 
4471
    strcpy(new_name_buff,new_name);
 
4472
    strcpy(new_alias= new_alias_buff, new_name);
4431
4473
    if (lower_case_table_names)
4432
4474
    {
4433
4475
      if (lower_case_table_names != 2)
4434
4476
      {
4435
 
        my_casedn_str(files_charset_info, new_name_buff);
4436
 
        new_alias= new_name;                    // Create lower case table name
 
4477
        my_casedn_str(files_charset_info, new_name_buff);
 
4478
        new_alias= new_name;                    // Create lower case table name
4437
4479
      }
4438
4480
      my_casedn_str(files_charset_info, new_name);
4439
4481
    }
4450
4492
    {
4451
4493
      if (table->s->tmp_table != NO_TMP_TABLE)
4452
4494
      {
4453
 
        if (find_temporary_table(thd,new_db,new_name_buff))
 
4495
        if (find_temporary_table(session,new_db,new_name_buff))
4454
4496
        {
4455
4497
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
4456
4498
          return(true);
4458
4500
      }
4459
4501
      else
4460
4502
      {
4461
 
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
 
4503
        if (lock_table_name_if_not_cached(session, new_db, new_name, &name_lock))
4462
4504
          return(true);
4463
4505
        if (!name_lock)
4464
4506
        {
4489
4531
    create_info->db_type= old_db_type;
4490
4532
  }
4491
4533
 
4492
 
  if (check_engine(thd, new_name, create_info))
 
4534
  if (check_engine(session, new_name, create_info))
4493
4535
    goto err;
4494
4536
  new_db_type= create_info->db_type;
4495
4537
 
4504
4546
  if (create_info->row_type == ROW_TYPE_NOT_USED)
4505
4547
    create_info->row_type= table->s->row_type;
4506
4548
 
4507
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
4508
 
      ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
 
4549
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_ALTER_NOT_SUPPORTED) ||
 
4550
      ha_check_storage_engine_flag(new_db_type, HTON_BIT_ALTER_NOT_SUPPORTED))
4509
4551
  {
4510
4552
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4511
4553
    goto err;
4512
4554
  }
4513
4555
 
4514
 
  thd_proc_info(thd, "setup");
 
4556
  session->set_proc_info("setup");
4515
4557
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4516
4558
      !table->s->tmp_table) // no need to touch frm
4517
4559
  {
4528
4570
        while the fact that the table is still open gives us protection
4529
4571
        from concurrent DDL statements.
4530
4572
      */
4531
 
      VOID(pthread_mutex_lock(&LOCK_open));
4532
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4533
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
4573
      pthread_mutex_lock(&LOCK_open);
 
4574
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
4575
      pthread_mutex_unlock(&LOCK_open);
4534
4576
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4535
4577
      /* COND_refresh will be signaled in close_thread_tables() */
4536
4578
      break;
4537
4579
    case DISABLE:
4538
 
      VOID(pthread_mutex_lock(&LOCK_open));
4539
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4540
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
4580
      pthread_mutex_lock(&LOCK_open);
 
4581
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
4582
      pthread_mutex_unlock(&LOCK_open);
4541
4583
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4542
4584
      /* COND_refresh will be signaled in close_thread_tables() */
4543
4585
      break;
4549
4591
    if (error == HA_ERR_WRONG_COMMAND)
4550
4592
    {
4551
4593
      error= 0;
4552
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4594
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4553
4595
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4554
4596
                          table->alias);
4555
4597
    }
4556
4598
 
4557
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
4599
    pthread_mutex_lock(&LOCK_open);
4558
4600
    /*
4559
4601
      Unlike to the above case close_cached_table() below will remove ALL
4560
4602
      instances of Table from table cache (it will also remove table lock
4566
4608
 
4567
4609
    if (!error && (new_name != table_name || new_db != db))
4568
4610
    {
4569
 
      thd_proc_info(thd, "rename");
 
4611
      session->set_proc_info("rename");
4570
4612
      /*
4571
4613
        Then do a 'simple' rename of the table. First we need to close all
4572
4614
        instances of 'source' table.
4573
4615
      */
4574
 
      close_cached_table(thd, table);
 
4616
      close_cached_table(session, table);
4575
4617
      /*
4576
4618
        Then, we want check once again that target table does not exist.
4577
4619
        Actually the order of these two steps does not matter since
4592
4634
          error= -1;
4593
4635
        else if (0)
4594
4636
      {
4595
 
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
4596
 
                                  table_name, 0));
 
4637
          mysql_rename_table(old_db_type, new_db, new_alias, db,
 
4638
                             table_name, 0);
4597
4639
          error= -1;
4598
4640
      }
4599
4641
    }
4602
4644
    if (error == HA_ERR_WRONG_COMMAND)
4603
4645
  {
4604
4646
      error= 0;
4605
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4647
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4606
4648
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4607
4649
                          table->alias);
4608
4650
  }
4609
4651
 
4610
4652
    if (!error)
4611
4653
    {
4612
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4613
 
      my_ok(thd);
 
4654
      write_bin_log(session, true, session->query, session->query_length);
 
4655
      my_ok(session);
4614
4656
  }
4615
4657
    else if (error > 0)
4616
4658
  {
4618
4660
      error= -1;
4619
4661
    }
4620
4662
    if (name_lock)
4621
 
      unlink_open_table(thd, name_lock, false);
4622
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4663
      unlink_open_table(session, name_lock, false);
 
4664
    pthread_mutex_unlock(&LOCK_open);
4623
4665
    table_list->table= NULL;                    // For query cache
4624
4666
    return(error);
4625
4667
  }
4639
4681
  */
4640
4682
  new_db_type= create_info->db_type;
4641
4683
 
4642
 
  if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
 
4684
  if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4643
4685
      goto err;
4644
4686
 
4645
 
  set_table_default_charset(thd, create_info, db);
4646
 
 
4647
 
 
4648
 
  if (thd->variables.old_alter_table
 
4687
  set_table_default_charset(session, create_info, db);
 
4688
 
 
4689
 
 
4690
  if (session->variables.old_alter_table
4649
4691
      || (table->s->db_type() != create_info->db_type)
4650
4692
     )
4651
4693
  {
4652
4694
    if (alter_info->build_method == HA_BUILD_ONLINE)
4653
4695
    {
4654
 
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4696
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4655
4697
      goto err;
4656
4698
    }
4657
4699
    alter_info->build_method= HA_BUILD_OFFLINE;
4662
4704
    Table *altered_table= 0;
4663
4705
    HA_ALTER_INFO ha_alter_info;
4664
4706
    HA_ALTER_FLAGS ha_alter_flags;
4665
 
    uint table_changes= IS_EQUAL_YES;
 
4707
    uint32_t table_changes= IS_EQUAL_YES;
4666
4708
    bool need_copy_table= true;
4667
4709
    /* Check how much the tables differ. */
4668
 
    if (compare_tables(thd, table, alter_info,
 
4710
    if (compare_tables(session, table, alter_info,
4669
4711
                       create_info, order_num,
4670
4712
                       &ha_alter_flags,
4671
4713
                       &ha_alter_info,
4688
4730
    if (new_name == table_name && new_db == db &&
4689
4731
        ha_alter_flags.is_set())
4690
4732
    {
4691
 
      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
 
4733
      Alter_info tmp_alter_info(*alter_info, session->mem_root);
4692
4734
 
4693
4735
      /*
4694
4736
        If no table rename,
4695
4737
        check if table can be altered on-line
4696
4738
      */
4697
 
      if (!(altered_table= create_altered_table(thd,
 
4739
      if (!(altered_table= create_altered_table(session,
4698
4740
                                                table,
4699
4741
                                                new_db,
4700
4742
                                                create_info,
4722
4764
      case HA_ALTER_NOT_SUPPORTED:
4723
4765
        if (alter_info->build_method == HA_BUILD_ONLINE)
4724
4766
        {
4725
 
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4726
 
          close_temporary_table(thd, altered_table, 1, 1);
 
4767
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
 
4768
          close_temporary_table(session, altered_table, 1, 1);
4727
4769
          goto err;
4728
4770
        }
4729
4771
        need_copy_table= true;
4730
4772
        break;
4731
4773
      case HA_ALTER_ERROR:
4732
4774
      default:
4733
 
        close_temporary_table(thd, altered_table, 1, 1);
 
4775
        close_temporary_table(session, altered_table, 1, 1);
4734
4776
        goto err;
4735
4777
      }
4736
4778
 
4741
4783
 
4742
4784
    if (!need_copy_table)
4743
4785
    {
4744
 
      error= mysql_fast_or_online_alter_table(thd,
 
4786
      error= mysql_fast_or_online_alter_table(session,
4745
4787
                                              table,
4746
4788
                                              altered_table,
4747
4789
                                              create_info,
4748
4790
                                              &ha_alter_info,
4749
4791
                                              &ha_alter_flags,
4750
4792
                                              alter_info->keys_onoff);
4751
 
      if (thd->lock)
 
4793
      if (session->lock)
4752
4794
      {
4753
 
        mysql_unlock_tables(thd, thd->lock);
4754
 
        thd->lock=0;
 
4795
        mysql_unlock_tables(session, session->lock);
 
4796
        session->lock=0;
4755
4797
      }
4756
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4798
      close_temporary_table(session, altered_table, 1, 1);
4757
4799
 
4758
4800
      if (error)
4759
4801
      {
4772
4814
    }
4773
4815
 
4774
4816
    if (altered_table)
4775
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4817
      close_temporary_table(session, altered_table, 1, 1);
4776
4818
  }
4777
4819
 
4778
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4779
 
           current_pid, thd->thread_id);
 
4820
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
 
4821
           (unsigned long)current_pid, session->thread_id);
4780
4822
  /* Safety fix for innodb */
4781
4823
  if (lower_case_table_names)
4782
4824
    my_casedn_str(files_charset_info, tmp_name);
4783
4825
 
4784
4826
 
4785
4827
  /* Create a temporary table with the new format */
4786
 
  if ((error= create_temporary_table(thd, table, new_db, tmp_name, 
4787
 
                                     create_info, alter_info, 
 
4828
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
 
4829
                                     create_info, alter_info,
4788
4830
                                     !strcmp(db, new_db))))
4789
4831
  {
4790
4832
    goto err;
4797
4839
    memset(&tbl, 0, sizeof(tbl));
4798
4840
    tbl.db= new_db;
4799
4841
    tbl.table_name= tbl.alias= tmp_name;
4800
 
    /* Table is in thd->temporary_tables */
4801
 
    new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
 
4842
    /* Table is in session->temporary_tables */
 
4843
    new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4802
4844
  }
4803
4845
  else
4804
4846
  {
4807
4849
    build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4808
4850
                         FN_IS_TMP);
4809
4851
    /* Open our intermediate table */
4810
 
    new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
 
4852
    new_table=open_temporary_table(session, path, new_db, tmp_name, 0, OTM_OPEN);
4811
4853
  }
4812
4854
  if (!new_table)
4813
4855
    goto err1;
4814
4856
 
4815
4857
  /* Copy the data if necessary. */
4816
 
  thd->count_cuted_fields= CHECK_FIELD_WARN;    // calc cuted fields
4817
 
  thd->cuted_fields=0L;
4818
 
  thd_proc_info(thd, "copy to tmp table");
 
4858
  session->count_cuted_fields= CHECK_FIELD_WARN;        // calc cuted fields
 
4859
  session->cuted_fields=0L;
 
4860
  session->set_proc_info("copy to tmp table");
4819
4861
  copied=deleted=0;
4820
4862
  /*
4821
4863
    We do not copy data for MERGE tables. Only the children have data.
4834
4876
  }
4835
4877
  else
4836
4878
  {
4837
 
    VOID(pthread_mutex_lock(&LOCK_open));
4838
 
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4839
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4879
    pthread_mutex_lock(&LOCK_open);
 
4880
    wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
4881
    pthread_mutex_unlock(&LOCK_open);
4840
4882
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4841
4883
                            alter_info->keys_onoff);
4842
 
    error= ha_autocommit_or_rollback(thd, 0);
4843
 
    if (end_active_trans(thd))
 
4884
    error= ha_autocommit_or_rollback(session, 0);
 
4885
    if (end_active_trans(session))
4844
4886
      error= 1;
4845
4887
  }
4846
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
4888
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
4847
4889
 
4848
4890
  if (table->s->tmp_table != NO_TMP_TABLE)
4849
4891
  {
4851
4893
    if (error)
4852
4894
      goto err1;
4853
4895
    /* Close lock if this is a transactional table */
4854
 
    if (thd->lock)
 
4896
    if (session->lock)
4855
4897
    {
4856
 
      mysql_unlock_tables(thd, thd->lock);
4857
 
      thd->lock=0;
 
4898
      mysql_unlock_tables(session, session->lock);
 
4899
      session->lock=0;
4858
4900
    }
4859
4901
    /* Remove link to old table and rename the new one */
4860
 
    close_temporary_table(thd, table, 1, 1);
 
4902
    close_temporary_table(session, table, 1, 1);
4861
4903
    /* Should pass the 'new_name' as we store table name in the cache */
4862
 
    if (rename_temporary_table(thd, new_table, new_db, new_name))
 
4904
    if (rename_temporary_table(session, new_table, new_db, new_name))
4863
4905
      goto err1;
4864
 
    /* We don't replicate alter table statement on temporary tables */
4865
 
    if (!thd->current_stmt_binlog_row_based)
4866
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4867
4906
    goto end_temporary;
4868
4907
  }
4869
4908
 
4874
4913
      Note that MERGE tables do not have their children attached here.
4875
4914
    */
4876
4915
    intern_close_table(new_table);
4877
 
    my_free(new_table,MYF(0));
 
4916
    free(new_table);
4878
4917
  }
4879
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
4918
  pthread_mutex_lock(&LOCK_open);
4880
4919
  if (error)
4881
4920
  {
4882
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4883
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4921
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
4922
    pthread_mutex_unlock(&LOCK_open);
4884
4923
    goto err;
4885
4924
  }
4886
4925
 
4900
4939
       call to remove name-locks from table cache and list of open table.
4901
4940
  */
4902
4941
 
4903
 
  thd_proc_info(thd, "rename result table");
4904
 
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
4905
 
           current_pid, thd->thread_id);
 
4942
  session->set_proc_info("rename result table");
 
4943
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
 
4944
           (unsigned long)current_pid, session->thread_id);
4906
4945
  if (lower_case_table_names)
4907
4946
    my_casedn_str(files_charset_info, old_name);
4908
4947
 
4909
 
  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4910
 
  close_data_files_and_morph_locks(thd, db, table_name);
 
4948
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
 
4949
  close_data_files_and_morph_locks(session, db, table_name);
4911
4950
 
4912
4951
  error=0;
4913
4952
  save_old_db_type= old_db_type;
4929
4968
                         FN_TO_IS_TMP))
4930
4969
  {
4931
4970
    error=1;
4932
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
4971
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4933
4972
  }
4934
4973
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
4935
4974
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
4936
4975
  {
4937
4976
    /* Try to get everything back. */
4938
4977
    error=1;
4939
 
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
4940
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4941
 
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
4942
 
                            FN_FROM_IS_TMP));
 
4978
    quick_rm_table(new_db_type,new_db,new_alias, 0);
 
4979
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
4980
    mysql_rename_table(old_db_type, db, old_name, db, alias,
 
4981
                       FN_FROM_IS_TMP);
4943
4982
  }
4944
4983
 
4945
4984
  if (error)
4948
4987
    goto err_with_placeholders;
4949
4988
  }
4950
4989
 
4951
 
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
 
4990
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4952
4991
 
4953
4992
end_online:
4954
 
  if (thd->locked_tables && new_name == table_name && new_db == db)
 
4993
  if (session->locked_tables && new_name == table_name && new_db == db)
4955
4994
  {
4956
 
    thd->in_lock_tables= 1;
4957
 
    error= reopen_tables(thd, 1, 1);
4958
 
    thd->in_lock_tables= 0;
 
4995
    session->in_lock_tables= 1;
 
4996
    error= reopen_tables(session, 1, 1);
 
4997
    session->in_lock_tables= 0;
4959
4998
    if (error)
4960
4999
      goto err_with_placeholders;
4961
5000
  }
4962
 
  VOID(pthread_mutex_unlock(&LOCK_open));
4963
 
 
4964
 
  thd_proc_info(thd, "end");
4965
 
 
4966
 
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
4967
 
                      thd->query, thd->query_length,
4968
 
                      db, table_name);
4969
 
 
4970
 
  assert(!(mysql_bin_log.is_open() &&
4971
 
                thd->current_stmt_binlog_row_based &&
 
5001
  pthread_mutex_unlock(&LOCK_open);
 
5002
 
 
5003
  session->set_proc_info("end");
 
5004
 
 
5005
  assert(!(drizzle_bin_log.is_open() &&
4972
5006
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4973
 
  write_bin_log(thd, true, thd->query, thd->query_length);
 
5007
  write_bin_log(session, true, session->query, session->query_length);
4974
5008
 
4975
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
 
5009
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
4976
5010
  {
4977
5011
    /*
4978
5012
      For the alter table to be properly flushed to the logs, we
4982
5016
    char path[FN_REFLEN];
4983
5017
    Table *t_table;
4984
5018
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
4985
 
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
 
5019
    t_table= open_temporary_table(session, path, new_db, tmp_name, false, OTM_OPEN);
4986
5020
    if (t_table)
4987
5021
    {
4988
5022
      intern_close_table(t_table);
4989
 
      my_free(t_table, MYF(0));
 
5023
      free(t_table);
4990
5024
    }
4991
5025
    else
4992
5026
      sql_print_warning(_("Could not open table %s.%s after rename\n"),
4995
5029
  }
4996
5030
  table_list->table=0;                          // For query cache
4997
5031
 
4998
 
  if (thd->locked_tables && (new_name != table_name || new_db != db))
 
5032
  if (session->locked_tables && (new_name != table_name || new_db != db))
4999
5033
  {
5000
5034
    /*
5001
5035
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
5004
5038
      LOCK TABLES we can rely on close_thread_tables() doing this job.
5005
5039
    */
5006
5040
    pthread_mutex_lock(&LOCK_open);
5007
 
    unlink_open_table(thd, table, false);
5008
 
    unlink_open_table(thd, name_lock, false);
 
5041
    unlink_open_table(session, table, false);
 
5042
    unlink_open_table(session, name_lock, false);
5009
5043
    pthread_mutex_unlock(&LOCK_open);
5010
5044
  }
5011
5045
 
5012
5046
end_temporary:
5013
5047
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5014
5048
           (ulong) (copied + deleted), (ulong) deleted,
5015
 
           (ulong) thd->cuted_fields);
5016
 
  my_ok(thd, copied + deleted, 0L, tmp_name);
5017
 
  thd->some_tables_deleted=0;
 
5049
           (ulong) session->cuted_fields);
 
5050
  my_ok(session, copied + deleted, 0L, tmp_name);
 
5051
  session->some_tables_deleted=0;
5018
5052
  return(false);
5019
5053
 
5020
5054
err1:
5021
5055
  if (new_table)
5022
5056
  {
5023
5057
    /* close_temporary_table() frees the new_table pointer. */
5024
 
    close_temporary_table(thd, new_table, 1, 1);
 
5058
    close_temporary_table(session, new_table, 1, 1);
5025
5059
  }
5026
5060
  else
5027
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5061
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5028
5062
 
5029
5063
err:
5030
5064
  /*
5033
5067
    the table to be altered isn't empty.
5034
5068
    Report error here.
5035
5069
  */
5036
 
  if (alter_info->error_if_not_empty && thd->row_count)
 
5070
  if (alter_info->error_if_not_empty && session->row_count)
5037
5071
  {
5038
5072
    const char *f_val= 0;
5039
5073
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
5040
5074
    switch (alter_info->datetime_field->sql_type)
5041
5075
    {
5042
 
      case DRIZZLE_TYPE_NEWDATE:
 
5076
      case DRIZZLE_TYPE_DATE:
5043
5077
        f_val= "0000-00-00";
5044
5078
        t_type= DRIZZLE_TIMESTAMP_DATE;
5045
5079
        break;
5051
5085
        /* Shouldn't get here. */
5052
5086
        assert(0);
5053
5087
    }
5054
 
    bool save_abort_on_warning= thd->abort_on_warning;
5055
 
    thd->abort_on_warning= true;
5056
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
5088
    bool save_abort_on_warning= session->abort_on_warning;
 
5089
    session->abort_on_warning= true;
 
5090
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5057
5091
                                 f_val, strlength(f_val), t_type,
5058
5092
                                 alter_info->datetime_field->field_name);
5059
 
    thd->abort_on_warning= save_abort_on_warning;
 
5093
    session->abort_on_warning= save_abort_on_warning;
5060
5094
  }
5061
5095
  if (name_lock)
5062
5096
  {
5063
5097
    pthread_mutex_lock(&LOCK_open);
5064
 
    unlink_open_table(thd, name_lock, false);
 
5098
    unlink_open_table(session, name_lock, false);
5065
5099
    pthread_mutex_unlock(&LOCK_open);
5066
5100
  }
5067
5101
  return(true);
5072
5106
    being altered. To be safe under LOCK TABLES we should remove placeholders
5073
5107
    from list of open tables list and table cache.
5074
5108
  */
5075
 
  unlink_open_table(thd, table, false);
 
5109
  unlink_open_table(session, table, false);
5076
5110
  if (name_lock)
5077
 
    unlink_open_table(thd, name_lock, false);
5078
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
5111
    unlink_open_table(session, name_lock, false);
 
5112
  pthread_mutex_unlock(&LOCK_open);
5079
5113
  return(true);
5080
5114
}
5081
5115
/* mysql_alter_table */
5084
5118
copy_data_between_tables(Table *from,Table *to,
5085
5119
                         List<Create_field> &create,
5086
5120
                         bool ignore,
5087
 
                         uint order_num, order_st *order,
 
5121
                         uint32_t order_num, order_st *order,
5088
5122
                         ha_rows *copied,
5089
5123
                         ha_rows *deleted,
5090
5124
                         enum enum_enable_or_disable keys_onoff,
5093
5127
  int error;
5094
5128
  Copy_field *copy,*copy_end;
5095
5129
  ulong found_count,delete_count;
5096
 
  THD *thd= current_thd;
5097
 
  uint length= 0;
 
5130
  Session *session= current_session;
 
5131
  uint32_t length= 0;
5098
5132
  SORT_FIELD *sortorder;
5099
5133
  READ_RECORD info;
5100
5134
  TableList   tables;
5108
5142
  /*
5109
5143
    Turn off recovery logging since rollback of an alter table is to
5110
5144
    delete the new table so there is no need to log the changes to it.
5111
 
    
 
5145
 
5112
5146
    This needs to be done before external_lock
5113
5147
  */
5114
 
  error= ha_enable_transaction(thd, false);
 
5148
  error= ha_enable_transaction(session, false);
5115
5149
  if (error)
5116
5150
    return(-1);
5117
 
  
 
5151
 
5118
5152
  if (!(copy= new Copy_field[to->s->fields]))
5119
5153
    return(-1);                         /* purecov: inspected */
5120
5154
 
5121
 
  if (to->file->ha_external_lock(thd, F_WRLCK))
 
5155
  if (to->file->ha_external_lock(session, F_WRLCK))
5122
5156
    return(-1);
5123
5157
 
5124
5158
  /* We need external lock before we can disable/enable keys */
5125
5159
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5126
5160
 
5127
5161
  /* We can abort alter table for any table type */
5128
 
  thd->abort_on_warning= !ignore;
 
5162
  session->abort_on_warning= !ignore;
5129
5163
 
5130
5164
  from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5131
5165
  to->file->ha_start_bulk_insert(from->file->stats.records);
5132
5166
 
5133
 
  save_sql_mode= thd->variables.sql_mode;
 
5167
  save_sql_mode= session->variables.sql_mode;
5134
5168
 
5135
5169
  List_iterator<Create_field> it(create);
5136
5170
  Create_field *def;
5155
5189
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5156
5190
    {
5157
5191
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
5158
 
      snprintf(warn_buff, sizeof(warn_buff), 
 
5192
      snprintf(warn_buff, sizeof(warn_buff),
5159
5193
               _("order_st BY ignored because there is a user-defined clustered "
5160
5194
                 "index in the table '%-.192s'"),
5161
5195
               from->s->table_name.str);
5162
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
5196
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5163
5197
                   warn_buff);
5164
5198
    }
5165
5199
    else
5166
5200
    {
5167
 
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5168
 
                                                MYF(MY_FAE | MY_ZEROFILL));
 
5201
      from->sort.io_cache=(IO_CACHE*) malloc(sizeof(IO_CACHE));
 
5202
      memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
 
5203
 
5169
5204
      memset(&tables, 0, sizeof(tables));
5170
5205
      tables.table= from;
5171
5206
      tables.alias= tables.table_name= from->s->table_name.str;
5172
5207
      tables.db= from->s->db.str;
5173
5208
      error= 1;
5174
5209
 
5175
 
      if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5176
 
          setup_order(thd, thd->lex->select_lex.ref_pointer_array,
 
5210
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
 
5211
          setup_order(session, session->lex->select_lex.ref_pointer_array,
5177
5212
                      &tables, fields, all_fields, order) ||
5178
5213
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5179
 
          (from->sort.found_records= filesort(thd, from, sortorder, length,
 
5214
          (from->sort.found_records= filesort(session, from, sortorder, length,
5180
5215
                                              (SQL_SELECT *) 0, HA_POS_ERROR,
5181
5216
                                              1, &examined_rows)) ==
5182
5217
          HA_POS_ERROR)
5186
5221
 
5187
5222
  /* Tell handler that we have values for all columns in the to table */
5188
5223
  to->use_all_columns();
5189
 
  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
 
5224
  init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
5190
5225
  if (ignore)
5191
5226
    to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5192
 
  thd->row_count= 0;
 
5227
  session->row_count= 0;
5193
5228
  restore_record(to, s->default_values);        // Create empty record
5194
5229
  while (!(error=info.read_record(&info)))
5195
5230
  {
5196
 
    if (thd->killed)
 
5231
    if (session->killed)
5197
5232
    {
5198
 
      thd->send_kill_message();
 
5233
      session->send_kill_message();
5199
5234
      error= 1;
5200
5235
      break;
5201
5236
    }
5202
 
    thd->row_count++;
 
5237
    session->row_count++;
5203
5238
    /* Return error if source table isn't empty. */
5204
5239
    if (error_if_not_empty)
5205
5240
    {
5213
5248
      else
5214
5249
        to->next_number_field->reset();
5215
5250
    }
5216
 
    
 
5251
 
5217
5252
    for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
5218
5253
    {
5219
5254
      copy_ptr->do_copy(copy_ptr);
5220
5255
    }
5221
5256
    prev_insert_id= to->file->next_insert_id;
 
5257
    update_virtual_fields_marked_for_write(to, false);
5222
5258
    error=to->file->ha_write_row(to->record[0]);
5223
5259
    to->auto_increment_field_not_null= false;
5224
5260
    if (error)
5228
5264
      {
5229
5265
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
5230
5266
         {
5231
 
           uint key_nr= to->file->get_dup_key(error);
 
5267
           uint32_t key_nr= to->file->get_dup_key(error);
5232
5268
           if ((int) key_nr >= 0)
5233
5269
           {
5234
5270
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
5261
5297
  }
5262
5298
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
5263
5299
 
5264
 
  if (ha_enable_transaction(thd, true))
 
5300
  if (ha_enable_transaction(session, true))
5265
5301
  {
5266
5302
    error= 1;
5267
5303
    goto err;
5271
5307
    Ensure that the new table is saved properly to disk so that we
5272
5308
    can do a rename
5273
5309
  */
5274
 
  if (ha_autocommit_or_rollback(thd, 0))
 
5310
  if (ha_autocommit_or_rollback(session, 0))
5275
5311
    error=1;
5276
 
  if (end_active_trans(thd))
 
5312
  if (end_active_trans(session))
5277
5313
    error=1;
5278
5314
 
5279
5315
 err:
5280
 
  thd->variables.sql_mode= save_sql_mode;
5281
 
  thd->abort_on_warning= 0;
 
5316
  session->variables.sql_mode= save_sql_mode;
 
5317
  session->abort_on_warning= 0;
5282
5318
  free_io_cache(from);
5283
5319
  *copied= found_count;
5284
5320
  *deleted=delete_count;
5285
5321
  to->file->ha_release_auto_increment();
5286
 
  if (to->file->ha_external_lock(thd,F_UNLCK))
 
5322
  if (to->file->ha_external_lock(session,F_UNLCK))
5287
5323
    error=1;
5288
5324
  return(error > 0 ? -1 : 0);
5289
5325
}
5294
5330
 
5295
5331
  SYNOPSIS
5296
5332
    mysql_recreate_table()
5297
 
    thd                 Thread handler
 
5333
    session                     Thread handler
5298
5334
    tables              Tables to recreate
5299
5335
 
5300
5336
 RETURN
5301
5337
    Like mysql_alter_table().
5302
5338
*/
5303
 
bool mysql_recreate_table(THD *thd, TableList *table_list)
 
5339
bool mysql_recreate_table(Session *session, TableList *table_list)
5304
5340
{
5305
5341
  HA_CREATE_INFO create_info;
5306
5342
  Alter_info alter_info;
5317
5353
  create_info.default_table_charset=default_charset_info;
5318
5354
  /* Force alter table to recreate table */
5319
5355
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5320
 
  return(mysql_alter_table(thd, NullS, NullS, &create_info,
 
5356
  return(mysql_alter_table(session, NULL, NULL, &create_info,
5321
5357
                                table_list, &alter_info, 0,
5322
5358
                                (order_st *) 0, 0));
5323
5359
}
5324
5360
 
5325
5361
 
5326
 
bool mysql_checksum_table(THD *thd, TableList *tables,
 
5362
bool mysql_checksum_table(Session *session, TableList *tables,
5327
5363
                          HA_CHECK_OPT *check_opt)
5328
5364
{
5329
5365
  TableList *table;
5330
5366
  List<Item> field_list;
5331
5367
  Item *item;
5332
 
  Protocol *protocol= thd->protocol;
 
5368
  Protocol *protocol= session->protocol;
5333
5369
 
5334
5370
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5335
5371
  item->maybe_null= 1;
5346
5382
    char table_name[NAME_LEN*2+2];
5347
5383
    Table *t;
5348
5384
 
5349
 
    strxmov(table_name, table->db ,".", table->table_name, NullS);
 
5385
    strxmov(table_name, table->db ,".", table->table_name, NULL);
5350
5386
 
5351
 
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5352
 
    thd->clear_error();                 // these errors shouldn't get client
 
5387
    t= table->table= open_n_lock_single_table(session, table, TL_READ);
 
5388
    session->clear_error();                     // these errors shouldn't get client
5353
5389
 
5354
5390
    protocol->prepare_for_resend();
5355
5391
    protocol->store(table_name, system_charset_info);
5358
5394
    {
5359
5395
      /* Table didn't exist */
5360
5396
      protocol->store_null();
5361
 
      thd->clear_error();
 
5397
      session->clear_error();
5362
5398
    }
5363
5399
    else
5364
5400
    {
5372
5408
      {
5373
5409
        /* calculating table's checksum */
5374
5410
        ha_checksum crc= 0;
5375
 
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
 
5411
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
5376
5412
 
5377
5413
        t->use_all_columns();
5378
5414
 
5400
5436
              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
5401
5437
            }
5402
5438
 
5403
 
            for (uint i= 0; i < t->s->fields; i++ )
 
5439
            for (uint32_t i= 0; i < t->s->fields; i++ )
5404
5440
            {
5405
5441
              Field *f= t->field[i];
5406
5442
              if ((f->type() == DRIZZLE_TYPE_BLOB) ||
5408
5444
              {
5409
5445
                String tmp;
5410
5446
                f->val_str(&tmp);
5411
 
                row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
 
5447
                row_crc= my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
5412
5448
              }
5413
5449
              else
5414
5450
                row_crc= my_checksum(row_crc, f->ptr,
5421
5457
          t->file->ha_rnd_end();
5422
5458
        }
5423
5459
      }
5424
 
      thd->clear_error();
5425
 
      close_thread_tables(thd);
 
5460
      session->clear_error();
 
5461
      close_thread_tables(session);
5426
5462
      table->table=0;                           // For query cache
5427
5463
    }
5428
5464
    if (protocol->write())
5429
5465
      goto err;
5430
5466
  }
5431
5467
 
5432
 
  my_eof(thd);
 
5468
  my_eof(session);
5433
5469
  return(false);
5434
5470
 
5435
5471
 err:
5436
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
5472
  close_thread_tables(session);                 // Shouldn't be needed
5437
5473
  if (table)
5438
5474
    table->table=0;
5439
5475
  return(true);
5440
5476
}
5441
5477
 
5442
 
static bool check_engine(THD *thd, const char *table_name,
 
5478
static bool check_engine(Session *session, const char *table_name,
5443
5479
                         HA_CREATE_INFO *create_info)
5444
5480
{
5445
5481
  handlerton **new_engine= &create_info->db_type;
5446
5482
  handlerton *req_engine= *new_engine;
5447
5483
  bool no_substitution= 1;
5448
 
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
 
5484
  if (!(*new_engine= ha_checktype(session, ha_legacy_type(req_engine),
5449
5485
                                  no_substitution, 1)))
5450
5486
    return true;
5451
5487
 
5452
5488
  if (req_engine && req_engine != *new_engine)
5453
5489
  {
5454
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5490
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5455
5491
                       ER_WARN_USING_OTHER_HANDLER,
5456
5492
                       ER(ER_WARN_USING_OTHER_HANDLER),
5457
5493
                       ha_resolve_storage_engine_name(*new_engine),
5458
5494
                       table_name);
5459
5495
  }
5460
5496
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5461
 
      ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
 
5497
      ha_check_storage_engine_flag(*new_engine, HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5462
5498
  {
5463
5499
    if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5464
5500
    {