~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

Show diffs side-by-side

added added

removed removed

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