~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Monty Taylor
  • Date: 2009-02-05 21:07:57 UTC
  • mto: This revision was merged to the branch mainline in revision 840.
  • Revision ID: mordred@inaugust.com-20090205210757-6487lf69y3mndcds
Fixed warnings badness in csv_alter_table test.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
#include <drizzled/server_includes.h>
19
19
#include <storage/myisam/myisam.h>
20
 
#include <drizzled/sql_show.h>
21
 
#include <drizzled/drizzled_error_messages.h>
 
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;
22
39
 
23
40
int creating_table= 0;        // How many mysql_create_table are running
24
41
 
25
 
const char *primary_key_name="PRIMARY";
 
42
 
 
43
bool is_primary_key(KEY *key_info)
 
44
{
 
45
  static const char * primary_key_name="PRIMARY";
 
46
  return (strcmp(key_info->name, primary_key_name)==0);
 
47
}
 
48
 
 
49
const char* is_primary_key_name(const char* key_name)
 
50
{
 
51
  static const char * primary_key_name="PRIMARY";
 
52
  if (strcmp(key_name, primary_key_name)==0)
 
53
    return key_name;
 
54
  else
 
55
    return NULL;
 
56
}
26
57
 
27
58
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
28
59
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
29
 
static int copy_data_between_tables(TABLE *from,TABLE *to,
 
60
static int copy_data_between_tables(Table *from,Table *to,
30
61
                                    List<Create_field> &create, bool ignore,
31
 
                                    uint order_num, ORDER *order,
 
62
                                    uint32_t order_num, order_st *order,
32
63
                                    ha_rows *copied,ha_rows *deleted,
33
64
                                    enum enum_enable_or_disable keys_onoff,
34
65
                                    bool error_if_not_empty);
35
66
 
36
 
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
37
 
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
 
67
static bool prepare_blob_field(Session *session, Create_field *sql_field);
 
68
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
38
69
static int
39
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
70
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
40
71
                           Alter_info *alter_info,
41
72
                           bool tmp_table,
42
 
                               uint *db_options,
 
73
                               uint32_t *db_options,
43
74
                               handler *file, KEY **key_info_buffer,
44
 
                               uint *key_count, int select_field_count);
 
75
                               uint32_t *key_count, int select_field_count);
45
76
static bool
46
 
mysql_prepare_alter_table(THD *thd, TABLE *table,
 
77
mysql_prepare_alter_table(Session *session, Table *table,
47
78
                          HA_CREATE_INFO *create_info,
48
79
                          Alter_info *alter_info);
49
80
 
 
81
static void set_table_default_charset(Session *session,
 
82
                                      HA_CREATE_INFO *create_info, char *db)
 
83
{
 
84
  /*
 
85
    If the table character set was not given explicitly,
 
86
    let's fetch the database default character set and
 
87
    apply it to the table.
 
88
  */
 
89
  if (!create_info->default_table_charset)
 
90
  {
 
91
    HA_CREATE_INFO db_info;
 
92
 
 
93
    load_db_opt_by_name(session, db, &db_info);
 
94
 
 
95
    create_info->default_table_charset= db_info.default_table_charset;
 
96
  }
 
97
}
 
98
 
50
99
/*
51
100
  Translate a file name to a table name (WL #1324).
52
101
 
59
108
  RETURN
60
109
    Table name length.
61
110
*/
62
 
uint filename_to_tablename(const char *from, char *to, uint to_length)
 
111
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
63
112
{
64
 
  uint errors;
65
 
  uint res;
 
113
  uint32_t errors;
 
114
  uint32_t res;
66
115
 
67
 
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
 
116
  if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
68
117
  {
69
118
    /* Temporary table name. */
70
 
    res= (stpncpy(to, from, to_length) - to);
 
119
    res= strlen(strncpy(to, from, to_length));
71
120
  }
72
121
  else
73
122
  {
75
124
                    system_charset_info,  to, to_length, &errors);
76
125
    if (errors) // Old 5.0 name
77
126
    {
78
 
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
79
 
            to);
80
 
      sql_print_error("Invalid (old?) table or database name '%s'", from);
81
 
      /*
82
 
        TODO: add a stored procedure for fix table and database names,
83
 
        and mention its name in error log.
84
 
      */
 
127
      strcpy(to, MYSQL50_TABLE_NAME_PREFIX);
 
128
      strncat(to, from, to_length-MYSQL50_TABLE_NAME_PREFIX_LENGTH-1);
 
129
      res= strlen(to);
 
130
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid (old?) table or database name '%s'"), from);
85
131
    }
86
132
  }
87
133
 
101
147
  RETURN
102
148
    File name length.
103
149
*/
104
 
 
105
 
uint tablename_to_filename(const char *from, char *to, uint to_length)
 
150
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
106
151
{
107
 
  uint errors, length;
 
152
  uint32_t errors, length;
108
153
 
109
154
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
110
155
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
111
 
    return((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
112
 
                                to_length-1) -
113
 
                        (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
 
156
    return((uint) (strncpy(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
 
157
                           to_length-1) -
 
158
                           (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
114
159
  length= strconvert(system_charset_info, from,
115
160
                     &my_charset_filename, to, to_length, &errors);
116
161
  if (check_if_legal_tablename(to) &&
124
169
 
125
170
 
126
171
/*
127
 
  Creates path to a file: mysql_data_dir/db/table.ext
 
172
  Creates path to a file: drizzle_data_dir/db/table.ext
128
173
 
129
174
  SYNOPSIS
130
175
   build_table_filename()
140
185
  NOTES
141
186
 
142
187
    Uses database and table name, and extension to create
143
 
    a file name in mysql_data_dir. Database and table
 
188
    a file name in drizzle_data_dir. Database and table
144
189
    names are converted from system_charset_info into "fscs".
145
190
    Unless flags indicate a temporary table name.
146
191
    'db' is always converted.
147
192
    'ext' is not converted.
148
193
 
149
 
    The conversion suppression is required for ALTER TABLE. This
 
194
    The conversion suppression is required for ALTER Table. This
150
195
    statement creates intermediate tables. These are regular
151
196
    (non-temporary) tables with a temporary name. Their path names must
152
197
    be derivable from the table name. So we cannot use
153
198
    build_tmptable_filename() for them.
154
199
 
155
200
  RETURN
156
 
    path length
 
201
    path length on success, 0 on failure
157
202
*/
158
203
 
159
 
uint build_table_filename(char *buff, size_t bufflen, const char *db,
160
 
                          const char *table_name, const char *ext, uint flags)
 
204
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
 
205
                          const char *table_name, const char *ext, uint32_t flags)
161
206
{
 
207
  string table_path;
162
208
  char dbbuff[FN_REFLEN];
163
209
  char tbbuff[FN_REFLEN];
 
210
  int rootdir_len= strlen(FN_ROOTDIR);
164
211
 
165
212
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
166
 
    stpncpy(tbbuff, table_name, sizeof(tbbuff));
 
213
    strncpy(tbbuff, table_name, sizeof(tbbuff));
167
214
  else
168
 
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
169
 
 
170
 
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
171
 
 
172
 
  char *end = buff + bufflen;
173
 
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
174
 
  char *pos = stpncpy(buff, mysql_data_home, bufflen);
175
 
  int rootdir_len= strlen(FN_ROOTDIR);
176
 
  if (pos - rootdir_len >= buff &&
177
 
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
178
 
    pos= stpncpy(pos, FN_ROOTDIR, end - pos);
179
 
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
 
215
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
 
216
 
 
217
  tablename_to_filename(db, dbbuff, sizeof(dbbuff));
 
218
  table_path= drizzle_data_home;
 
219
  int without_rootdir= table_path.length()-rootdir_len;
 
220
 
 
221
  /* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
 
222
  if (without_rootdir >= 0)
 
223
  {
 
224
    char *tmp= (char*)table_path.c_str()+without_rootdir;
 
225
    if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
 
226
      table_path.append(FN_ROOTDIR);
 
227
  }
 
228
 
 
229
  table_path.append(dbbuff);
 
230
  table_path.append(FN_ROOTDIR);
180
231
#ifdef USE_SYMDIR
181
 
  unpack_dirname(buff, buff);
182
 
  pos= strend(buff);
 
232
  table_path.clear();
183
233
#endif
184
 
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
185
 
 
186
 
  return(pos - buff);
 
234
  table_path.append(tbbuff);
 
235
  table_path.append(ext);
 
236
 
 
237
  if (bufflen < table_path.length())
 
238
    return 0;
 
239
 
 
240
  strcpy(buff, table_path.c_str());
 
241
  return table_path.length();
187
242
}
188
243
 
189
244
 
190
245
/*
191
 
  Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
 
246
  Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
192
247
 
193
248
  SYNOPSIS
194
249
   build_tmptable_filename()
195
 
     thd                        The thread handle.
 
250
     session                    The thread handle.
196
251
     buff                       Where to write result in my_charset_filename.
197
252
     bufflen                    buff size
198
253
 
199
254
  NOTES
200
255
 
201
256
    Uses current_pid, thread_id, and tmp_table counter to create
202
 
    a file name in mysql_tmpdir.
 
257
    a file name in drizzle_tmpdir.
203
258
 
204
259
  RETURN
205
 
    path length
 
260
    path length on success, 0 on failure
206
261
*/
207
262
 
208
 
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
 
263
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
209
264
{
 
265
  uint32_t length;
 
266
  ostringstream path_str, post_tmpdir_str;
 
267
  string tmp;
210
268
 
211
 
  char *p= stpncpy(buff, mysql_tmpdir, bufflen);
212
 
  snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
213
 
              tmp_file_prefix, current_pid,
214
 
              thd->thread_id, thd->tmp_table++, reg_ext);
 
269
  path_str << drizzle_tmpdir;
 
270
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
 
271
  post_tmpdir_str << session->thread_id << session->tmp_table++ << reg_ext;
 
272
  tmp= post_tmpdir_str.str();
215
273
 
216
274
  if (lower_case_table_names)
217
 
  {
218
 
    /* Convert all except tmpdir to lower case */
219
 
    my_casedn_str(files_charset_info, p);
220
 
  }
221
 
 
222
 
  uint length= unpack_filename(buff, buff);
223
 
  return(length);
 
275
    transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
 
276
 
 
277
  path_str << tmp;
 
278
 
 
279
  if (bufflen < path_str.str().length())
 
280
    length= 0;
 
281
  else
 
282
    length= unpack_filename(buff, path_str.str().c_str());
 
283
 
 
284
  return length;
224
285
}
225
286
 
226
287
/*
227
288
  SYNOPSIS
228
289
    write_bin_log()
229
 
    thd                           Thread object
 
290
    session                           Thread object
230
291
    clear_error                   is clear_error to be called
231
292
    query                         Query to log
232
293
    query_length                  Length of query
239
300
    file
240
301
*/
241
302
 
242
 
void write_bin_log(THD *thd, bool clear_error,
243
 
                   char const *query, ulong query_length)
 
303
void write_bin_log(Session *session, bool,
 
304
                   char const *query, size_t query_length)
244
305
{
245
 
  if (mysql_bin_log.is_open())
246
 
  {
247
 
    if (clear_error)
248
 
      thd->clear_error();
249
 
    thd->binlog_query(THD::STMT_QUERY_TYPE,
250
 
                      query, query_length, false, false);
251
 
  }
 
306
  (void)replicator_statement(session, query, query_length);
252
307
}
253
308
 
254
309
 
257
312
 
258
313
  SYNOPSIS
259
314
   mysql_rm_table()
260
 
   thd                  Thread handle
 
315
   session                      Thread handle
261
316
   tables               List of tables to delete
262
317
   if_exists            If 1, don't give error if one table doesn't exists
263
318
 
276
331
 
277
332
*/
278
333
 
279
 
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists, bool drop_temporary)
 
334
bool mysql_rm_table(Session *session,TableList *tables, bool if_exists, bool drop_temporary)
280
335
{
281
336
  bool error, need_start_waiting= false;
282
337
 
283
338
  if (tables && tables->schema_table)
284
339
  {
285
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
340
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
286
341
    return(true);
287
342
  }
288
343
 
290
345
 
291
346
  if (!drop_temporary)
292
347
  {
293
 
    if (!thd->locked_tables &&
294
 
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
348
    if (!session->locked_tables &&
 
349
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
295
350
      return(true);
296
351
  }
297
352
 
300
355
    LOCK_open during wait_if_global_read_lock(), other threads could not
301
356
    close their tables. This would make a pretty deadlock.
302
357
  */
303
 
  error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
 
358
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0);
304
359
 
305
360
  if (need_start_waiting)
306
 
    start_waiting_global_read_lock(thd);
 
361
    start_waiting_global_read_lock(session);
307
362
 
308
363
  if (error)
309
364
    return(true);
310
 
  my_ok(thd);
 
365
  session->my_ok();
311
366
  return(false);
312
367
}
313
368
 
316
371
 
317
372
  SYNOPSIS
318
373
    mysql_rm_table_part2()
319
 
    thd                 Thread handler
 
374
    session                     Thread handler
320
375
    tables              Tables to drop
321
376
    if_exists           If set, don't give an error if table doesn't exists.
322
377
                        In this case we give an warning of level 'NOTE'
323
378
    drop_temporary      Only drop temporary tables
324
379
    drop_view           Allow to delete VIEW .frm
325
380
    dont_log_query      Don't write query to log files. This will also not
326
 
                        generate warnings if the handler files doesn't exists  
 
381
                        generate warnings if the handler files doesn't exists
327
382
 
328
383
  TODO:
329
384
    When logging to the binary log, we should log
341
396
   -1   Thread was killed
342
397
*/
343
398
 
344
 
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
345
 
                         bool drop_temporary, bool drop_view,
346
 
                         bool dont_log_query)
 
399
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
 
400
                         bool drop_temporary, bool dont_log_query)
347
401
{
348
 
  TABLE_LIST *table;
 
402
  TableList *table;
349
403
  char path[FN_REFLEN], *alias;
350
 
  uint path_length;
 
404
  uint32_t path_length= 0;
351
405
  String wrong_tables;
352
406
  int error= 0;
353
407
  int non_temp_tables_count= 0;
354
408
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
355
409
  String built_query;
356
410
 
357
 
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
411
  if (!dont_log_query)
358
412
  {
359
413
    built_query.set_charset(system_charset_info);
360
414
    if (if_exists)
361
 
      built_query.append("DROP TABLE IF EXISTS ");
 
415
      built_query.append("DROP Table IF EXISTS ");
362
416
    else
363
 
      built_query.append("DROP TABLE ");
 
417
      built_query.append("DROP Table ");
364
418
  }
365
419
 
366
 
  mysql_ha_rm_tables(thd, tables, false);
 
420
  mysql_ha_rm_tables(session, tables, false);
367
421
 
368
422
  pthread_mutex_lock(&LOCK_open);
369
423
 
381
435
      table->db_type= share->db_type();
382
436
  }
383
437
 
384
 
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
 
438
  if (!drop_temporary && lock_table_names_exclusively(session, tables))
385
439
  {
386
440
    pthread_mutex_unlock(&LOCK_open);
387
441
    return(1);
388
442
  }
389
443
 
390
444
  /* Don't give warnings for not found errors, as we already generate notes */
391
 
  thd->no_warnings_for_error= 1;
 
445
  session->no_warnings_for_error= 1;
392
446
 
393
447
  for (table= tables; table; table= table->next_local)
394
448
  {
395
449
    char *db=table->db;
396
450
    handlerton *table_type;
397
 
    enum legacy_db_type frm_db_type;
398
 
 
399
 
 
400
 
    error= drop_temporary_table(thd, table);
 
451
 
 
452
    error= drop_temporary_table(session, table);
401
453
 
402
454
    switch (error) {
403
455
    case  0:
405
457
      tmp_table_deleted= 1;
406
458
      continue;
407
459
    case -1:
408
 
      assert(thd->in_sub_stmt);
409
460
      error= 1;
410
461
      goto err_with_placeholders;
411
462
    default:
419
470
      being built.  The string always end in a comma and the comma
420
471
      will be chopped off before being written to the binary log.
421
472
      */
422
 
    if (thd->current_stmt_binlog_row_based && !dont_log_query)
 
473
    if (!dont_log_query)
423
474
    {
424
475
      non_temp_tables_count++;
425
476
      /*
426
477
        Don't write the database name if it is the current one (or if
427
 
        thd->db is NULL).
 
478
        session->db is NULL).
428
479
      */
429
480
      built_query.append("`");
430
 
      if (thd->db == NULL || strcmp(db,thd->db) != 0)
 
481
      if (session->db == NULL || strcmp(db,session->db) != 0)
431
482
      {
432
483
        built_query.append(db);
433
484
        built_query.append("`.`");
440
491
    table_type= table->db_type;
441
492
    if (!drop_temporary)
442
493
    {
443
 
      TABLE *locked_table;
444
 
      abort_locked_tables(thd, db, table->table_name);
445
 
      remove_table_from_cache(thd, db, table->table_name,
 
494
      Table *locked_table;
 
495
      abort_locked_tables(session, db, table->table_name);
 
496
      remove_table_from_cache(session, db, table->table_name,
446
497
                              RTFC_WAIT_OTHER_THREAD_FLAG |
447
498
                              RTFC_CHECK_KILLED_FLAG);
448
499
      /*
449
500
        If the table was used in lock tables, remember it so that
450
501
        unlock_table_names can free it
451
502
      */
452
 
      if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
 
503
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
453
504
        table->table= locked_table;
454
505
 
455
 
      if (thd->killed)
 
506
      if (session->killed)
456
507
      {
457
508
        error= -1;
458
509
        goto err_with_placeholders;
464
515
                                        FN_IS_TMP : 0);
465
516
    }
466
517
    if (drop_temporary ||
467
 
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
468
 
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
 
518
        ((table_type == NULL && (access(path, F_OK))))
 
519
        )
469
520
    {
470
521
      // Table was not found on disk and table can't be created from engine
471
522
      if (if_exists)
472
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
523
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
473
524
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
474
525
                            table->table_name);
475
526
      else
478
529
    else
479
530
    {
480
531
      char *end;
481
 
      if (table_type == NULL)
482
 
      {
483
 
        mysql_frm_type(thd, path, &frm_db_type);
484
 
        table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
485
 
      }
486
532
      // Remove extension for delete
487
533
      *(end= path + path_length - reg_ext_length)= '\0';
488
 
      error= ha_delete_table(thd, table_type, path, db, table->table_name,
 
534
      error= ha_delete_table(session, path, db, table->table_name,
489
535
                             !dont_log_query);
490
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
491
 
          (if_exists || table_type == NULL))
 
536
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
 
537
          if_exists)
492
538
      {
493
539
        error= 0;
494
 
        thd->clear_error();
 
540
        session->clear_error();
495
541
      }
496
542
      if (error == HA_ERR_ROW_IS_REFERENCED)
497
543
      {
501
547
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
502
548
      {
503
549
        int new_error;
 
550
 
 
551
        /* for some weird-ass reason, we ignore the return code here
 
552
           and things work. */
 
553
        delete_table_proto_file(path);
 
554
 
504
555
        /* Delete the table definition file */
505
 
        stpcpy(end,reg_ext);
 
556
        strcpy(end,reg_ext);
506
557
        if (!(new_error=my_delete(path,MYF(MY_WME))))
507
558
        {
508
559
          some_tables_deleted=1;
523
574
    on the table name.
524
575
  */
525
576
  pthread_mutex_unlock(&LOCK_open);
526
 
  thd->thread_specific_used|= tmp_table_deleted;
 
577
  session->thread_specific_used|= tmp_table_deleted;
527
578
  error= 0;
528
579
  if (wrong_tables.length())
529
580
  {
541
592
  {
542
593
    if (!dont_log_query)
543
594
    {
544
 
      if (!thd->current_stmt_binlog_row_based ||
545
 
          (non_temp_tables_count > 0 && !tmp_table_deleted))
 
595
      if ((non_temp_tables_count > 0 && !tmp_table_deleted))
546
596
      {
547
597
        /*
548
598
          In this case, we are either using statement-based
551
601
          tables).  In this case, we can write the original query into
552
602
          the binary log.
553
603
         */
554
 
        write_bin_log(thd, !error, thd->query, thd->query_length);
 
604
        write_bin_log(session, !error, session->query, session->query_length);
555
605
      }
556
 
      else if (thd->current_stmt_binlog_row_based &&
557
 
               non_temp_tables_count > 0 &&
 
606
      else if (non_temp_tables_count > 0 &&
558
607
               tmp_table_deleted)
559
608
      {
560
609
        /*
571
620
        */
572
621
        built_query.chop();                  // Chop of the last comma
573
622
        built_query.append(" /* generated by server */");
574
 
        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
 
623
        write_bin_log(session, !error, built_query.ptr(), built_query.length());
575
624
      }
576
625
      /*
577
626
        The remaining cases are:
585
634
  }
586
635
  pthread_mutex_lock(&LOCK_open);
587
636
err_with_placeholders:
588
 
  unlock_table_names(thd, tables, (TABLE_LIST*) 0);
 
637
  unlock_table_names(session, tables, (TableList*) 0);
589
638
  pthread_mutex_unlock(&LOCK_open);
590
 
  thd->no_warnings_for_error= 0;
 
639
  session->no_warnings_for_error= 0;
591
640
  return(error);
592
641
}
593
642
 
607
656
    != 0        Error
608
657
*/
609
658
 
610
 
bool quick_rm_table(handlerton *base,const char *db,
611
 
                    const char *table_name, uint flags)
 
659
bool quick_rm_table(handlerton *,const char *db,
 
660
                    const char *table_name, uint32_t flags)
612
661
{
613
662
  char path[FN_REFLEN];
614
663
  bool error= 0;
615
664
 
616
 
  uint path_length= build_table_filename(path, sizeof(path),
 
665
  uint32_t path_length= build_table_filename(path, sizeof(path),
617
666
                                         db, table_name, reg_ext, flags);
618
667
  if (my_delete(path,MYF(0)))
619
668
    error= 1; /* purecov: inspected */
 
669
 
620
670
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
621
 
  return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
 
671
 
 
672
  error|= delete_table_proto_file(path);
 
673
 
 
674
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
622
675
              error);
623
676
}
624
677
 
638
691
static int sort_keys(KEY *a, KEY *b)
639
692
{
640
693
  ulong a_flags= a->flags, b_flags= b->flags;
641
 
  
 
694
 
642
695
  if (a_flags & HA_NOSAME)
643
696
  {
644
697
    if (!(b_flags & HA_NOSAME))
648
701
      /* Sort NOT NULL keys before other keys */
649
702
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
650
703
    }
651
 
    if (a->name == primary_key_name)
 
704
    if (is_primary_key(a))
652
705
      return -1;
653
 
    if (b->name == primary_key_name)
 
706
    if (is_primary_key(b))
654
707
      return 1;
655
708
    /* Sort keys don't containing partial segments before others */
656
709
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
694
747
  TYPELIB tmp= *typelib;
695
748
  const char **cur_value= typelib->type_names;
696
749
  unsigned int *cur_length= typelib->type_lengths;
697
 
  *dup_val_count= 0;  
698
 
  
 
750
  *dup_val_count= 0;
 
751
 
699
752
  for ( ; tmp.count > 1; cur_value++, cur_length++)
700
753
  {
701
754
    tmp.type_names++;
734
787
                                uint32_t *max_length, uint32_t *tot_length)
735
788
{
736
789
  const char **pos;
737
 
  uint *len;
 
790
  uint32_t *len;
738
791
  *max_length= *tot_length= 0;
739
792
  for (pos= interval->type_names, len= interval->type_lengths;
740
793
       *pos ; pos++, len++)
741
794
  {
742
 
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
 
795
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
743
796
    *tot_length+= length;
744
797
    set_if_bigger(*max_length, (uint32_t)length);
745
798
  }
765
818
   1    Error
766
819
*/
767
820
 
768
 
int prepare_create_field(Create_field *sql_field, 
769
 
                         uint *blob_columns,
 
821
int prepare_create_field(Create_field *sql_field,
 
822
                         uint32_t *blob_columns,
770
823
                         int *timestamps, int *timestamps_with_niladic,
771
 
                         int64_t table_flags __attribute__((unused)))
 
824
                         int64_t )
772
825
{
773
826
  unsigned int dup_val_count;
774
827
 
805
858
                                     sql_field->charset, &dup_val_count))
806
859
      return(1);
807
860
    break;
808
 
  case DRIZZLE_TYPE_NEWDATE:  // Rest of string types
 
861
  case DRIZZLE_TYPE_DATE:  // Rest of string types
809
862
  case DRIZZLE_TYPE_TIME:
810
863
  case DRIZZLE_TYPE_DATETIME:
811
864
  case DRIZZLE_TYPE_NULL:
843
896
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
844
897
    break;
845
898
  }
846
 
  if (!(sql_field->flags & NOT_NULL_FLAG))
 
899
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
 
900
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
847
901
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
848
902
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
849
903
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
855
909
 
856
910
  SYNOPSIS
857
911
    mysql_prepare_create_table()
858
 
      thd                       Thread object.
 
912
      session                       Thread object.
859
913
      create_info               Create information (like MAX_ROWS).
860
914
      alter_info                List of columns and indexes to create
861
915
      tmp_table                 If a temporary table is to be created.
877
931
*/
878
932
 
879
933
static int
880
 
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
 
934
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
881
935
                           Alter_info *alter_info,
882
936
                           bool tmp_table,
883
 
                               uint *db_options,
 
937
                               uint32_t *db_options,
884
938
                               handler *file, KEY **key_info_buffer,
885
 
                               uint *key_count, int select_field_count)
 
939
                               uint32_t *key_count, int select_field_count)
886
940
{
887
941
  const char    *key_name;
888
942
  Create_field  *sql_field,*dup_field;
895
949
  int           select_field_pos,auto_increment=0;
896
950
  List_iterator<Create_field> it(alter_info->create_list);
897
951
  List_iterator<Create_field> it2(alter_info->create_list);
898
 
  uint total_uneven_bit_length= 0;
 
952
  uint32_t total_uneven_bit_length= 0;
899
953
 
900
954
  select_field_pos= alter_info->create_list.elements - select_field_count;
901
955
  null_fields=blob_columns=0;
915
969
    if (!sql_field->charset)
916
970
      sql_field->charset= create_info->default_table_charset;
917
971
    /*
918
 
      table_charset is set in ALTER TABLE if we want change character set
 
972
      table_charset is set in ALTER Table if we want change character set
919
973
      for all varchar/char columns.
920
974
      But the table charset must not affect the BLOB fields, so don't
921
975
      allow to change my_charset_bin to somethig else.
929
983
                                                    MY_CS_BINSORT,MYF(0))))
930
984
    {
931
985
      char tmp[64];
932
 
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
933
 
              STRING_WITH_LEN("_bin"));
 
986
      char *tmp_pos= tmp;
 
987
      strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
 
988
      tmp_pos+= strlen(tmp);
 
989
      strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
934
990
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
935
991
      return(true);
936
992
    }
939
995
      Convert the default value from client character
940
996
      set into the column character set if necessary.
941
997
    */
942
 
    if (sql_field->def && 
 
998
    if (sql_field->def &&
943
999
        save_cs != sql_field->def->collation.collation &&
944
1000
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
945
1001
    {
981
1037
          occupied memory at the same time when we free this
982
1038
          sql_field -- at the end of execution.
983
1039
        */
984
 
        interval= sql_field->interval= typelib(thd->mem_root,
 
1040
        interval= sql_field->interval= typelib(session->mem_root,
985
1041
                                               sql_field->interval_list);
986
1042
        List_iterator<String> int_it(sql_field->interval_list);
987
1043
        String conv, *tmp;
988
1044
        char comma_buf[4];
989
 
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
990
 
                                          (uchar*) comma_buf + 
 
1045
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
 
1046
                                          (unsigned char*) comma_buf +
991
1047
                                          sizeof(comma_buf));
992
1048
        assert(comma_length > 0);
993
 
        for (uint i= 0; (tmp= int_it++); i++)
 
1049
        for (uint32_t i= 0; (tmp= int_it++); i++)
994
1050
        {
995
 
          uint lengthsp;
 
1051
          uint32_t lengthsp;
996
1052
          if (String::needs_conversion(tmp->length(), tmp->charset(),
997
1053
                                       cs, &dummy))
998
1054
          {
999
 
            uint cnv_errs;
 
1055
            uint32_t cnv_errs;
1000
1056
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
1001
 
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
 
1057
            interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
1002
1058
                                                  conv.length());
1003
1059
            interval->type_lengths[i]= conv.length();
1004
1060
          }
1007
1063
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
1008
1064
                                       interval->type_lengths[i]);
1009
1065
          interval->type_lengths[i]= lengthsp;
1010
 
          ((uchar *)interval->type_names[i])[lengthsp]= '\0';
 
1066
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
1011
1067
        }
1012
1068
        sql_field->interval_list.empty(); // Don't need interval_list anymore
1013
1069
      }
1028
1084
            }
1029
1085
 
1030
1086
            /* else, the defaults yield the correct length for NULLs. */
1031
 
          } 
 
1087
          }
1032
1088
          else /* not NULL */
1033
1089
          {
1034
1090
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
1046
1102
    }
1047
1103
 
1048
1104
    sql_field->create_length_to_internal_length();
1049
 
    if (prepare_blob_field(thd, sql_field))
 
1105
    if (prepare_blob_field(session, sql_field))
1050
1106
      return(true);
1051
1107
 
1052
1108
    if (!(sql_field->flags & NOT_NULL_FLAG))
1088
1144
          sql_field->decimals=          dup_field->decimals;
1089
1145
          sql_field->create_length_to_internal_length();
1090
1146
          sql_field->unireg_check=      dup_field->unireg_check;
1091
 
          /* 
 
1147
          /*
1092
1148
            We're making one field from two, the result field will have
1093
1149
            dup_field->flags as flags. If we've incremented null_fields
1094
1150
            because of sql_field->flags, decrement it back.
1097
1153
            null_fields--;
1098
1154
          sql_field->flags=             dup_field->flags;
1099
1155
          sql_field->interval=          dup_field->interval;
 
1156
          sql_field->vcol_info=         dup_field->vcol_info;
 
1157
          sql_field->is_stored=      dup_field->is_stored;
1100
1158
          it2.remove();                 // Remove first (create) definition
1101
1159
          select_field_pos--;
1102
1160
          break;
1119
1177
  {
1120
1178
    assert(sql_field->charset != 0);
1121
1179
 
1122
 
    if (prepare_create_field(sql_field, &blob_columns, 
 
1180
    if (prepare_create_field(sql_field, &blob_columns,
1123
1181
                             &timestamps, &timestamps_with_niladic,
1124
1182
                             file->ha_table_flags()))
1125
1183
      return(true);
1128
1186
    sql_field->offset= record_offset;
1129
1187
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1130
1188
      auto_increment++;
1131
 
    record_offset+= sql_field->pack_length;
 
1189
    /*
 
1190
          For now skip fields that are not physically stored in the database
 
1191
          (virtual fields) and update their offset later
 
1192
          (see the next loop).
 
1193
        */
 
1194
    if (sql_field->is_stored)
 
1195
      record_offset+= sql_field->pack_length;
 
1196
  }
 
1197
  /* Update virtual fields' offset */
 
1198
  it.rewind();
 
1199
  while ((sql_field=it++))
 
1200
  {
 
1201
    if (not sql_field->is_stored)
 
1202
    {
 
1203
      sql_field->offset= record_offset;
 
1204
      record_offset+= sql_field->pack_length;
 
1205
    }
1132
1206
  }
1133
1207
  if (timestamps_with_niladic > 1)
1134
1208
  {
1160
1234
 
1161
1235
  List_iterator<Key> key_iterator(alter_info->key_list);
1162
1236
  List_iterator<Key> key_iterator2(alter_info->key_list);
1163
 
  uint key_parts=0, fk_key_count=0;
 
1237
  uint32_t key_parts=0, fk_key_count=0;
1164
1238
  bool primary_key=0,unique_key=0;
1165
1239
  Key *key, *key2;
1166
 
  uint tmp, key_number;
 
1240
  uint32_t tmp, key_number;
1167
1241
  /* special marker for keys to be ignored */
1168
1242
  static char ignore_key[1];
1169
1243
 
1175
1249
    if (key->type == Key::FOREIGN_KEY)
1176
1250
    {
1177
1251
      fk_key_count++;
 
1252
      if (((Foreign_key *)key)->validate(alter_info->create_list))
 
1253
        return true;
1178
1254
      Foreign_key *fk_key= (Foreign_key*) key;
1179
1255
      if (fk_key->ref_columns.elements &&
1180
1256
          fk_key->ref_columns.elements != fk_key->columns.elements)
1231
1307
    else
1232
1308
      (*key_count)--;
1233
1309
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
1234
 
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
 
1310
        is_primary_key_name(key->name.str))
1235
1311
    {
1236
1312
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1237
1313
      return(true);
1253
1329
  key_number=0;
1254
1330
  for (; (key=key_iterator++) ; key_number++)
1255
1331
  {
1256
 
    uint key_length=0;
 
1332
    uint32_t key_length=0;
1257
1333
    Key_part_spec *column;
1258
1334
 
1259
1335
    if (key->name.str == ignore_key)
1297
1373
    if (key_info->block_size)
1298
1374
      key_info->flags|= HA_USES_BLOCK_SIZE;
1299
1375
 
1300
 
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
1376
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
1301
1377
                                           key->key_create_info.comment.str,
1302
1378
                                           key->key_create_info.comment.str +
1303
1379
                                           key->key_create_info.comment.length,
1319
1395
    }
1320
1396
 
1321
1397
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
1322
 
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
 
1398
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
1323
1399
    {
1324
 
      uint length;
 
1400
      uint32_t length;
1325
1401
      Key_part_spec *dup_column;
1326
1402
 
1327
1403
      it.rewind();
1364
1440
            return(true);
1365
1441
          }
1366
1442
        }
 
1443
        if (not sql_field->is_stored)
 
1444
        {
 
1445
          /* Key fields must always be physically stored. */
 
1446
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
 
1447
          return(true);
 
1448
        }
 
1449
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
 
1450
        {
 
1451
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
 
1452
          return(true);
 
1453
        }
1367
1454
        if (!(sql_field->flags & NOT_NULL_FLAG))
1368
1455
        {
1369
1456
          if (key->type == Key::PRIMARY)
1402
1489
          if ((length=column->length) > max_key_length ||
1403
1490
              length > file->max_key_part_length())
1404
1491
          {
1405
 
            length=min(max_key_length, file->max_key_part_length());
 
1492
            length=cmin(max_key_length, file->max_key_part_length());
1406
1493
            if (key->type == Key::MULTIPLE)
1407
1494
            {
1408
1495
              /* not a critical problem */
1409
1496
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
1410
1497
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1411
1498
                       length);
1412
 
              push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1499
              push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1413
1500
                           ER_TOO_LONG_KEY, warn_buff);
1414
1501
              /* Align key length to multibyte char boundary */
1415
1502
              length-= length % sql_field->charset->mbmaxlen;
1448
1535
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
1449
1536
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1450
1537
                   length);
1451
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1538
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1452
1539
                       ER_TOO_LONG_KEY, warn_buff);
1453
1540
          /* Align key length to multibyte char boundary */
1454
1541
          length-= length % sql_field->charset->mbmaxlen;
1490
1577
                       MYF(0));
1491
1578
            return(true);
1492
1579
          }
1493
 
          key_name=primary_key_name;
 
1580
          static const char pkey_name[]= "PRIMARY";
 
1581
          key_name=pkey_name;
1494
1582
          primary_key=1;
1495
1583
        }
1496
1584
        else if (!(key_name= key->name.str))
1531
1619
    return(true);
1532
1620
  }
1533
1621
  /* Sort keys in optimized order */
1534
 
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
 
1622
  my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
1535
1623
           (qsort_cmp) sort_keys);
1536
1624
  create_info->null_bits= null_fields;
1537
1625
 
1541
1629
  {
1542
1630
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1543
1631
 
1544
 
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
 
1632
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1545
1633
        !sql_field->def &&
1546
1634
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1547
1635
        (sql_field->flags & NOT_NULL_FLAG) &&
1569
1657
  return(false);
1570
1658
}
1571
1659
 
1572
 
 
1573
 
/*
1574
 
  Set table default charset, if not set
1575
 
 
1576
 
  SYNOPSIS
1577
 
    set_table_default_charset()
1578
 
    create_info        Table create information
1579
 
 
1580
 
  DESCRIPTION
1581
 
    If the table character set was not given explicitely,
1582
 
    let's fetch the database default character set and
1583
 
    apply it to the table.
1584
 
*/
1585
 
 
1586
 
static void set_table_default_charset(THD *thd,
1587
 
                                      HA_CREATE_INFO *create_info, char *db)
1588
 
{
1589
 
  /*
1590
 
    If the table character set was not given explicitly,
1591
 
    let's fetch the database default character set and
1592
 
    apply it to the table.
1593
 
  */
1594
 
  if (!create_info->default_table_charset)
1595
 
  {
1596
 
    HA_CREATE_INFO db_info;
1597
 
 
1598
 
    load_db_opt_by_name(thd, db, &db_info);
1599
 
 
1600
 
    create_info->default_table_charset= db_info.default_table_charset;
1601
 
  }
1602
 
}
1603
 
 
1604
 
 
1605
1660
/*
1606
1661
  Extend long VARCHAR fields to blob & prepare field if it's a blob
1607
1662
 
1615
1670
        In this case the error is given
1616
1671
*/
1617
1672
 
1618
 
static bool prepare_blob_field(THD *thd __attribute__((unused)),
 
1673
static bool prepare_blob_field(Session *,
1619
1674
                               Create_field *sql_field)
1620
1675
{
1621
1676
 
1626
1681
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1627
1682
    return(1);
1628
1683
  }
1629
 
    
 
1684
 
1630
1685
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1631
1686
  {
1632
1687
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1642
1697
 
1643
1698
 
1644
1699
/*
1645
 
  Preparation of Create_field for SP function return values.
1646
 
  Based on code used in the inner loop of mysql_prepare_create_table()
1647
 
  above.
1648
 
 
1649
 
  SYNOPSIS
1650
 
    sp_prepare_create_field()
1651
 
    thd                 Thread object
1652
 
    sql_field           Field to prepare
1653
 
 
1654
 
  DESCRIPTION
1655
 
    Prepares the field structures for field creation.
1656
 
 
1657
 
*/
1658
 
 
1659
 
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
1660
 
{
1661
 
  if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
1662
 
  {
1663
 
    uint32_t field_length, dummy;
1664
 
    /* DRIZZLE_TYPE_ENUM */
1665
 
    {
1666
 
      calculate_interval_lengths(sql_field->charset,
1667
 
                                 sql_field->interval,
1668
 
                                 &field_length, &dummy);
1669
 
      sql_field->length= field_length;
1670
 
    }
1671
 
    set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
1672
 
  }
1673
 
 
1674
 
  sql_field->create_length_to_internal_length();
1675
 
  assert(sql_field->def == 0);
1676
 
  /* Can't go wrong as sql_field->def is not defined */
1677
 
  (void) prepare_blob_field(thd, sql_field);
1678
 
}
1679
 
 
1680
 
 
1681
 
/*
1682
1700
  Create a table
1683
1701
 
1684
1702
  SYNOPSIS
1685
1703
    mysql_create_table_no_lock()
1686
 
    thd                 Thread object
 
1704
    session                     Thread object
1687
1705
    db                  Database
1688
1706
    table_name          Table name
1689
1707
    create_info         Create information (like MAX_ROWS)
1690
1708
    fields              List of fields to create
1691
1709
    keys                List of keys to create
1692
1710
    internal_tmp_table  Set to 1 if this is an internal temporary table
1693
 
                        (From ALTER TABLE)
1694
 
    select_field_count  
 
1711
                        (From ALTER Table)
 
1712
    select_field_count
1695
1713
 
1696
1714
  DESCRIPTION
1697
1715
    If one creates a temporary table, this is automatically opened
1711
1729
    true  error
1712
1730
*/
1713
1731
 
1714
 
bool mysql_create_table_no_lock(THD *thd,
 
1732
bool mysql_create_table_no_lock(Session *session,
1715
1733
                                const char *db, const char *table_name,
1716
1734
                                HA_CREATE_INFO *create_info,
1717
1735
                                Alter_info *alter_info,
1718
1736
                                bool internal_tmp_table,
1719
 
                                uint select_field_count)
 
1737
                                uint32_t select_field_count,
 
1738
                                bool lock_open_lock)
1720
1739
{
1721
1740
  char          path[FN_REFLEN];
1722
 
  uint          path_length;
 
1741
  uint32_t          path_length;
1723
1742
  const char    *alias;
1724
1743
  uint          db_options, key_count;
1725
1744
  KEY           *key_info_buffer;
1732
1751
               MYF(0));
1733
1752
    return(true);
1734
1753
  }
1735
 
  if (check_engine(thd, table_name, create_info))
 
1754
  if (check_engine(session, table_name, create_info))
1736
1755
    return(true);
1737
1756
  db_options= create_info->table_options;
1738
1757
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1739
1758
    db_options|=HA_OPTION_PACK_RECORD;
1740
1759
  alias= table_case_name(create_info, table_name);
1741
 
  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
 
1760
  if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1742
1761
                              create_info->db_type)))
1743
1762
  {
1744
1763
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1745
1764
    return(true);
1746
1765
  }
1747
1766
 
1748
 
  set_table_default_charset(thd, create_info, (char*) db);
 
1767
  set_table_default_charset(session, create_info, (char*) db);
1749
1768
 
1750
 
  if (mysql_prepare_create_table(thd, create_info, alter_info,
 
1769
  if (mysql_prepare_create_table(session, create_info, alter_info,
1751
1770
                                 internal_tmp_table,
1752
1771
                                 &db_options, file,
1753
1772
                          &key_info_buffer, &key_count,
1757
1776
      /* Check if table exists */
1758
1777
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1759
1778
  {
1760
 
    path_length= build_tmptable_filename(thd, path, sizeof(path));
 
1779
    path_length= build_tmptable_filename(session, path, sizeof(path));
1761
1780
    create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1762
1781
  }
1763
 
  else  
 
1782
  else
1764
1783
  {
1765
1784
 #ifdef FN_DEVCHAR
1766
1785
    /* check if the table name contains FN_DEVCHAR when defined */
1776
1795
 
1777
1796
  /* Check if table already exists */
1778
1797
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1779
 
      find_temporary_table(thd, db, table_name))
 
1798
      find_temporary_table(session, db, table_name))
1780
1799
  {
1781
1800
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1782
1801
    {
1783
1802
      create_info->table_existed= 1;            // Mark that table existed
1784
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1803
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1785
1804
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1786
1805
                          alias);
1787
1806
      error= 0;
1791
1810
    goto err;
1792
1811
  }
1793
1812
 
1794
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
1813
  if (lock_open_lock)
 
1814
    pthread_mutex_lock(&LOCK_open);
1795
1815
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1796
1816
  {
1797
1817
    if (!access(path,F_OK))
1829
1849
  {
1830
1850
    bool create_if_not_exists =
1831
1851
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1832
 
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
 
1852
    int retcode = ha_table_exists_in_engine(session, db, table_name);
1833
1853
    switch (retcode)
1834
1854
    {
1835
1855
      case HA_ERR_NO_SUCH_TABLE:
1848
1868
    }
1849
1869
  }
1850
1870
 
1851
 
  thd_proc_info(thd, "creating table");
 
1871
  session->set_proc_info("creating table");
1852
1872
  create_info->table_existed= 0;                // Mark that table is created
1853
1873
 
1854
1874
#ifdef HAVE_READLINK
1867
1887
#endif /* HAVE_READLINK */
1868
1888
  {
1869
1889
    if (create_info->data_file_name)
1870
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1890
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1871
1891
                   "DATA DIRECTORY option ignored");
1872
1892
    if (create_info->index_file_name)
1873
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
1893
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1874
1894
                   "INDEX DIRECTORY option ignored");
1875
1895
    create_info->data_file_name= create_info->index_file_name= 0;
1876
1896
  }
1877
1897
  create_info->table_options=db_options;
1878
1898
 
1879
1899
  path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1880
 
  if (rea_create_table(thd, path, db, table_name,
 
1900
  if (rea_create_table(session, path, db, table_name,
1881
1901
                       create_info, alter_info->create_list,
1882
 
                       key_count, key_info_buffer, file))
 
1902
                       key_count, key_info_buffer, file, false))
1883
1903
    goto unlock_and_end;
1884
1904
 
1885
1905
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1886
1906
  {
1887
1907
    /* Open table and put in temporary table list */
1888
 
    if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
 
1908
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1889
1909
    {
1890
 
      (void) rm_temporary_table(create_info->db_type, path, false);
 
1910
      (void) rm_temporary_table(create_info->db_type, path);
1891
1911
      goto unlock_and_end;
1892
1912
    }
1893
 
    thd->thread_specific_used= true;
 
1913
    session->thread_specific_used= true;
1894
1914
  }
1895
1915
 
1896
1916
  /*
1901
1921
    Otherwise, the statement shall be binlogged.
1902
1922
   */
1903
1923
  if (!internal_tmp_table &&
1904
 
      (!thd->current_stmt_binlog_row_based ||
1905
 
       (thd->current_stmt_binlog_row_based &&
1906
 
        !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1907
 
    write_bin_log(thd, true, thd->query, thd->query_length);
 
1924
      ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
 
1925
    write_bin_log(session, true, session->query, session->query_length);
1908
1926
  error= false;
1909
1927
unlock_and_end:
1910
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
1928
  if (lock_open_lock)
 
1929
    pthread_mutex_unlock(&LOCK_open);
1911
1930
 
1912
1931
err:
1913
 
  thd_proc_info(thd, "After create");
 
1932
  session->set_proc_info("After create");
1914
1933
  delete file;
1915
1934
  return(error);
1916
1935
 
1917
1936
warn:
1918
1937
  error= false;
1919
 
  push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1938
  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1920
1939
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1921
1940
                      alias);
1922
1941
  create_info->table_existed= 1;                // Mark that table existed
1928
1947
  Database locking aware wrapper for mysql_create_table_no_lock(),
1929
1948
*/
1930
1949
 
1931
 
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
 
1950
bool mysql_create_table(Session *session, const char *db, const char *table_name,
1932
1951
                        HA_CREATE_INFO *create_info,
1933
1952
                        Alter_info *alter_info,
1934
1953
                        bool internal_tmp_table,
1935
 
                        uint select_field_count)
 
1954
                        uint32_t select_field_count)
1936
1955
{
1937
 
  TABLE *name_lock= 0;
 
1956
  Table *name_lock= 0;
1938
1957
  bool result;
1939
1958
 
1940
1959
  /* Wait for any database locks */
1941
1960
  pthread_mutex_lock(&LOCK_lock_db);
1942
 
  while (!thd->killed &&
1943
 
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
 
1961
  while (!session->killed &&
 
1962
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
1944
1963
  {
1945
 
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1964
    wait_for_condition(session, &LOCK_lock_db, &COND_refresh);
1946
1965
    pthread_mutex_lock(&LOCK_lock_db);
1947
1966
  }
1948
1967
 
1949
 
  if (thd->killed)
 
1968
  if (session->killed)
1950
1969
  {
1951
1970
    pthread_mutex_unlock(&LOCK_lock_db);
1952
1971
    return(true);
1956
1975
 
1957
1976
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1958
1977
  {
1959
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
1978
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
1960
1979
    {
1961
1980
      result= true;
1962
1981
      goto unlock;
1965
1984
    {
1966
1985
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1967
1986
      {
1968
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1987
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1969
1988
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1970
1989
                            table_name);
1971
1990
        create_info->table_existed= 1;
1980
1999
    }
1981
2000
  }
1982
2001
 
1983
 
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
 
2002
  result= mysql_create_table_no_lock(session, db, table_name, create_info,
1984
2003
                                     alter_info,
1985
2004
                                     internal_tmp_table,
1986
 
                                     select_field_count);
 
2005
                                     select_field_count, true);
1987
2006
 
1988
2007
unlock:
1989
2008
  if (name_lock)
1990
2009
  {
1991
2010
    pthread_mutex_lock(&LOCK_open);
1992
 
    unlink_open_table(thd, name_lock, false);
 
2011
    unlink_open_table(session, name_lock, false);
1993
2012
    pthread_mutex_unlock(&LOCK_open);
1994
2013
  }
1995
2014
  pthread_mutex_lock(&LOCK_lock_db);
2020
2039
  char buff[MAX_FIELD_NAME],*buff_end;
2021
2040
 
2022
2041
  if (!check_if_keyname_exists(field_name,start,end) &&
2023
 
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
 
2042
      !is_primary_key_name(field_name))
2024
2043
    return (char*) field_name;                  // Use fieldname
2025
 
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
 
2044
 
 
2045
  buff_end= strncpy(buff, field_name, sizeof(buff)-4);
 
2046
  buff_end+= strlen(buff);
2026
2047
 
2027
2048
  /*
2028
2049
    Only 3 chars + '\0' left, so need to limit to 2 digit
2029
2050
    This is ok as we can't have more than 100 keys anyway
2030
2051
  */
2031
 
  for (uint i=2 ; i< 100; i++)
 
2052
  for (uint32_t i=2 ; i< 100; i++)
2032
2053
  {
2033
2054
    *buff_end= '_';
2034
2055
    int10_to_str(i, buff_end+1, 10);
2068
2089
bool
2069
2090
mysql_rename_table(handlerton *base, const char *old_db,
2070
2091
                   const char *old_name, const char *new_db,
2071
 
                   const char *new_name, uint flags)
 
2092
                   const char *new_name, uint32_t flags)
2072
2093
{
2073
 
  THD *thd= current_thd;
 
2094
  Session *session= current_session;
2074
2095
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2075
2096
  char *from_base= from, *to_base= to;
2076
2097
  char tmp_name[NAME_LEN+1];
2078
2099
  int error=0;
2079
2100
 
2080
2101
  file= (base == NULL ? 0 :
2081
 
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
 
2102
         get_new_handler((TABLE_SHARE*) 0, session->mem_root, base));
2082
2103
 
2083
2104
  build_table_filename(from, sizeof(from), old_db, old_name, "",
2084
2105
                       flags & FN_FROM_IS_TMP);
2093
2114
  if (lower_case_table_names == 2 && file &&
2094
2115
      !(file->ha_table_flags() & HA_FILE_BASED))
2095
2116
  {
2096
 
    stpcpy(tmp_name, old_name);
 
2117
    strcpy(tmp_name, old_name);
2097
2118
    my_casedn_str(files_charset_info, tmp_name);
2098
2119
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2099
2120
                         flags & FN_FROM_IS_TMP);
2100
2121
    from_base= lc_from;
2101
2122
 
2102
 
    stpcpy(tmp_name, new_name);
 
2123
    strcpy(tmp_name, new_name);
2103
2124
    my_casedn_str(files_charset_info, tmp_name);
2104
2125
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2105
2126
                         flags & FN_TO_IS_TMP);
2114
2135
      if (file)
2115
2136
        file->ha_rename_table(to_base, from_base);
2116
2137
    }
 
2138
 
 
2139
    if(!(flags & NO_FRM_RENAME)
 
2140
       && rename_table_proto_file(from_base, to_base))
 
2141
    {
 
2142
      error= errno;
 
2143
      rename_file_ext(to, from, reg_ext);
 
2144
      if (file)
 
2145
        file->ha_rename_table(to_base, from_base);
 
2146
    }
2117
2147
  }
2118
2148
  delete file;
2119
2149
  if (error == HA_ERR_WRONG_COMMAND)
2120
 
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
 
2150
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
2121
2151
  else if (error)
2122
2152
    my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
2123
2153
  return(error != 0);
2129
2159
 
2130
2160
  SYNOPSIS
2131
2161
    wait_while_table_is_used()
2132
 
    thd                 Thread handler
 
2162
    session                     Thread handler
2133
2163
    table               Table to remove from cache
2134
2164
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2135
2165
                        HA_EXTRA_FORCE_REOPEN if table is not be used
2143
2173
    Win32 clients must also have a WRITE LOCK on the table !
2144
2174
*/
2145
2175
 
2146
 
void wait_while_table_is_used(THD *thd, TABLE *table,
 
2176
void wait_while_table_is_used(Session *session, Table *table,
2147
2177
                              enum ha_extra_function function)
2148
2178
{
2149
2179
 
2150
2180
  safe_mutex_assert_owner(&LOCK_open);
2151
2181
 
2152
 
  VOID(table->file->extra(function));
 
2182
  table->file->extra(function);
2153
2183
  /* Mark all tables that are in use as 'old' */
2154
 
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
 
2184
  mysql_lock_abort(session, table, true);       /* end threads waiting on lock */
2155
2185
 
2156
2186
  /* Wait until all there are no other threads that has this table open */
2157
 
  remove_table_from_cache(thd, table->s->db.str,
 
2187
  remove_table_from_cache(session, table->s->db.str,
2158
2188
                          table->s->table_name.str,
2159
2189
                          RTFC_WAIT_OTHER_THREAD_FLAG);
2160
2190
  return;
2165
2195
 
2166
2196
  SYNOPSIS
2167
2197
    close_cached_table()
2168
 
    thd                 Thread handler
 
2198
    session                     Thread handler
2169
2199
    table               Table to remove from cache
2170
2200
 
2171
2201
  NOTES
2177
2207
    Win32 clients must also have a WRITE LOCK on the table !
2178
2208
*/
2179
2209
 
2180
 
void close_cached_table(THD *thd, TABLE *table)
 
2210
void close_cached_table(Session *session, Table *table)
2181
2211
{
2182
2212
 
2183
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
2213
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2184
2214
  /* Close lock if this is not got with LOCK TABLES */
2185
 
  if (thd->lock)
 
2215
  if (session->lock)
2186
2216
  {
2187
 
    mysql_unlock_tables(thd, thd->lock);
2188
 
    thd->lock=0;                        // Start locked threads
 
2217
    mysql_unlock_tables(session, session->lock);
 
2218
    session->lock=0;                    // Start locked threads
2189
2219
  }
2190
2220
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
2191
 
  unlink_open_table(thd, table, true);
 
2221
  unlink_open_table(session, table, true);
2192
2222
 
2193
2223
  /* When lock on LOCK_open is freed other threads can continue */
2194
2224
  broadcast_refresh();
2195
2225
  return;
2196
2226
}
2197
2227
 
2198
 
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
 
2228
static int send_check_errmsg(Session *session, TableList* table,
2199
2229
                             const char* operator_name, const char* errmsg)
2200
2230
 
2201
2231
{
2202
 
  Protocol *protocol= thd->protocol;
 
2232
  Protocol *protocol= session->protocol;
2203
2233
  protocol->prepare_for_resend();
2204
2234
  protocol->store(table->alias, system_charset_info);
2205
2235
  protocol->store((char*) operator_name, system_charset_info);
2206
2236
  protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2207
2237
  protocol->store(errmsg, system_charset_info);
2208
 
  thd->clear_error();
 
2238
  session->clear_error();
2209
2239
  if (protocol->write())
2210
2240
    return -1;
2211
2241
  return 1;
2212
2242
}
2213
2243
 
2214
2244
 
2215
 
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
 
2245
static int prepare_for_repair(Session *session, TableList *table_list,
2216
2246
                              HA_CHECK_OPT *check_opt)
2217
2247
{
2218
2248
  int error= 0;
2219
 
  TABLE tmp_table, *table;
 
2249
  Table tmp_table, *table;
2220
2250
  TABLE_SHARE *share;
2221
2251
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
2222
2252
  const char **ext;
2223
2253
  struct stat stat_info;
2224
2254
 
2225
 
  if (!(check_opt->sql_flags & TT_USEFRM))
 
2255
  if (!(check_opt->use_frm))
2226
2256
    return(0);
2227
2257
 
2228
2258
  if (!(table= table_list->table))              /* if open_ltable failed */
2229
2259
  {
2230
2260
    char key[MAX_DBKEY_LENGTH];
2231
 
    uint key_length;
 
2261
    uint32_t key_length;
2232
2262
 
2233
 
    key_length= create_table_def_key(thd, key, table_list, 0);
 
2263
    key_length= create_table_def_key(session, key, table_list, 0);
2234
2264
    pthread_mutex_lock(&LOCK_open);
2235
 
    if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
 
2265
    if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2236
2266
                                  &error))))
2237
2267
    {
2238
2268
      pthread_mutex_unlock(&LOCK_open);
2239
2269
      return(0);                                // Can't open frm file
2240
2270
    }
2241
2271
 
2242
 
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
 
2272
    if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2243
2273
    {
2244
2274
      release_table_share(share, RELEASE_NORMAL);
2245
2275
      pthread_mutex_unlock(&LOCK_open);
2250
2280
  }
2251
2281
 
2252
2282
  /*
2253
 
    REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
 
2283
    REPAIR Table ... USE_FRM for temporary tables makes little sense.
2254
2284
  */
2255
2285
  if (table->s->tmp_table)
2256
2286
  {
2257
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2287
    error= send_check_errmsg(session, table_list, "repair",
2258
2288
                             "Cannot repair temporary table from .frm file");
2259
2289
    goto end;
2260
2290
  }
2273
2303
    Check if this is a table type that stores index and data separately,
2274
2304
    like ISAM or MyISAM. We assume fixed order of engine file name
2275
2305
    extentions array. First element of engine file name extentions array
2276
 
    is meta/index file extention. Second element - data file extention. 
 
2306
    is meta/index file extention. Second element - data file extention.
2277
2307
  */
2278
2308
  ext= table->file->bas_ext();
2279
2309
  if (!ext[0] || !ext[1])
2280
2310
    goto end;                                   // No data file
2281
2311
 
2282
2312
  // Name of data file
2283
 
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
 
2313
  sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2284
2314
  if (stat(from, &stat_info))
2285
2315
    goto end;                           // Can't use USE_FRM flag
2286
2316
 
2287
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2288
 
           from, current_pid, thd->thread_id);
 
2317
  snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
 
2318
           from, (unsigned long)current_pid, session->thread_id);
2289
2319
 
2290
2320
  /* If we could open the table, close it */
2291
2321
  if (table_list->table)
2292
2322
  {
2293
2323
    pthread_mutex_lock(&LOCK_open);
2294
 
    close_cached_table(thd, table);
 
2324
    close_cached_table(session, table);
2295
2325
    pthread_mutex_unlock(&LOCK_open);
2296
2326
  }
2297
 
  if (lock_and_wait_for_table_name(thd,table_list))
 
2327
  if (lock_and_wait_for_table_name(session,table_list))
2298
2328
  {
2299
2329
    error= -1;
2300
2330
    goto end;
2302
2332
  if (my_rename(from, tmp, MYF(MY_WME)))
2303
2333
  {
2304
2334
    pthread_mutex_lock(&LOCK_open);
2305
 
    unlock_table_name(thd, table_list);
 
2335
    unlock_table_name(session, table_list);
2306
2336
    pthread_mutex_unlock(&LOCK_open);
2307
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2337
    error= send_check_errmsg(session, table_list, "repair",
2308
2338
                             "Failed renaming data file");
2309
2339
    goto end;
2310
2340
  }
2311
 
  if (mysql_truncate(thd, table_list, 1))
 
2341
  if (mysql_truncate(session, table_list, 1))
2312
2342
  {
2313
2343
    pthread_mutex_lock(&LOCK_open);
2314
 
    unlock_table_name(thd, table_list);
 
2344
    unlock_table_name(session, table_list);
2315
2345
    pthread_mutex_unlock(&LOCK_open);
2316
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2346
    error= send_check_errmsg(session, table_list, "repair",
2317
2347
                             "Failed generating table from .frm file");
2318
2348
    goto end;
2319
2349
  }
2320
2350
  if (my_rename(tmp, from, MYF(MY_WME)))
2321
2351
  {
2322
2352
    pthread_mutex_lock(&LOCK_open);
2323
 
    unlock_table_name(thd, table_list);
 
2353
    unlock_table_name(session, table_list);
2324
2354
    pthread_mutex_unlock(&LOCK_open);
2325
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2355
    error= send_check_errmsg(session, table_list, "repair",
2326
2356
                             "Failed restoring .MYD file");
2327
2357
    goto end;
2328
2358
  }
2332
2362
    to finish the repair in the handler later on.
2333
2363
  */
2334
2364
  pthread_mutex_lock(&LOCK_open);
2335
 
  if (reopen_name_locked_table(thd, table_list, true))
 
2365
  if (reopen_name_locked_table(session, table_list, true))
2336
2366
  {
2337
 
    unlock_table_name(thd, table_list);
 
2367
    unlock_table_name(session, table_list);
2338
2368
    pthread_mutex_unlock(&LOCK_open);
2339
 
    error= send_check_errmsg(thd, table_list, "repair",
 
2369
    error= send_check_errmsg(session, table_list, "repair",
2340
2370
                             "Failed to open partially repaired table");
2341
2371
    goto end;
2342
2372
  }
2346
2376
  if (table == &tmp_table)
2347
2377
  {
2348
2378
    pthread_mutex_lock(&LOCK_open);
2349
 
    closefrm(table, 1);                         // Free allocated memory
 
2379
    table->closefrm(true);                              // Free allocated memory
2350
2380
    pthread_mutex_unlock(&LOCK_open);
2351
2381
  }
2352
2382
  return(error);
2357
2387
/*
2358
2388
  RETURN VALUES
2359
2389
    false Message sent to net (admin operation went ok)
2360
 
    true  Message should be sent by caller 
 
2390
    true  Message should be sent by caller
2361
2391
          (admin operation or network communication failed)
2362
2392
*/
2363
 
static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
 
2393
static bool mysql_admin_table(Session* session, TableList* tables,
2364
2394
                              HA_CHECK_OPT* check_opt,
2365
2395
                              const char *operator_name,
2366
2396
                              thr_lock_type lock_type,
2367
2397
                              bool open_for_modify,
2368
2398
                              bool no_warnings_for_error,
2369
 
                              uint extra_open_options,
2370
 
                              int (*prepare_func)(THD *, TABLE_LIST *,
 
2399
                              uint32_t extra_open_options,
 
2400
                              int (*prepare_func)(Session *, TableList *,
2371
2401
                                                  HA_CHECK_OPT *),
2372
 
                              int (handler::*operator_func)(THD *,
 
2402
                              int (handler::*operator_func)(Session *,
2373
2403
                                                            HA_CHECK_OPT *))
2374
2404
{
2375
 
  TABLE_LIST *table;
2376
 
  SELECT_LEX *select= &thd->lex->select_lex;
 
2405
  TableList *table;
 
2406
  SELECT_LEX *select= &session->lex->select_lex;
2377
2407
  List<Item> field_list;
2378
2408
  Item *item;
2379
 
  Protocol *protocol= thd->protocol;
2380
 
  LEX *lex= thd->lex;
 
2409
  Protocol *protocol= session->protocol;
 
2410
  LEX *lex= session->lex;
2381
2411
  int result_code= 0;
2382
2412
  const CHARSET_INFO * const cs= system_charset_info;
2383
2413
 
2384
 
  if (end_active_trans(thd))
 
2414
  if (end_active_trans(session))
2385
2415
    return(1);
2386
2416
  field_list.push_back(item = new Item_empty_string("Table",
2387
2417
                                                    NAME_CHAR_LEN * 2,
2397
2427
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2398
2428
    return(true);
2399
2429
 
2400
 
  mysql_ha_rm_tables(thd, tables, false);
 
2430
  mysql_ha_rm_tables(session, tables, false);
2401
2431
 
2402
2432
  for (table= tables; table; table= table->next_local)
2403
2433
  {
2405
2435
    char* db = table->db;
2406
2436
    bool fatal_error=0;
2407
2437
 
2408
 
    strxmov(table_name, db, ".", table->table_name, NullS);
2409
 
    thd->open_options|= extra_open_options;
 
2438
    sprintf(table_name,"%s.%s",db,table->table_name);
 
2439
    session->open_options|= extra_open_options;
2410
2440
    table->lock_type= lock_type;
2411
2441
    /* open only one table from local list of command */
2412
2442
    {
2413
 
      TABLE_LIST *save_next_global, *save_next_local;
 
2443
      TableList *save_next_global, *save_next_local;
2414
2444
      save_next_global= table->next_global;
2415
2445
      table->next_global= 0;
2416
2446
      save_next_local= table->next_local;
2417
2447
      table->next_local= 0;
2418
 
      select->table_list.first= (uchar*)table;
 
2448
      select->table_list.first= (unsigned char*)table;
2419
2449
      /*
2420
2450
        Time zone tables and SP tables can be add to lex->query_tables list,
2421
2451
        so it have to be prepared.
2425
2455
      lex->query_tables= table;
2426
2456
      lex->query_tables_last= &table->next_global;
2427
2457
      lex->query_tables_own_last= 0;
2428
 
      thd->no_warnings_for_error= no_warnings_for_error;
2429
 
      table->required_type=FRMTYPE_TABLE;
 
2458
      session->no_warnings_for_error= no_warnings_for_error;
2430
2459
 
2431
 
      open_and_lock_tables(thd, table);
2432
 
      thd->no_warnings_for_error= 0;
 
2460
      open_and_lock_tables(session, table);
 
2461
      session->no_warnings_for_error= 0;
2433
2462
      table->next_global= save_next_global;
2434
2463
      table->next_local= save_next_local;
2435
 
      thd->open_options&= ~extra_open_options;
 
2464
      session->open_options&= ~extra_open_options;
2436
2465
    }
2437
2466
 
2438
2467
    if (prepare_func)
2439
2468
    {
2440
 
      switch ((*prepare_func)(thd, table, check_opt)) {
 
2469
      switch ((*prepare_func)(session, table, check_opt)) {
2441
2470
      case  1:           // error, message written to net
2442
 
        ha_autocommit_or_rollback(thd, 1);
2443
 
        end_trans(thd, ROLLBACK);
2444
 
        close_thread_tables(thd);
 
2471
        ha_autocommit_or_rollback(session, 1);
 
2472
        end_trans(session, ROLLBACK);
 
2473
        close_thread_tables(session);
2445
2474
        continue;
2446
2475
      case -1:           // error, message could be written to net
2447
2476
        /* purecov: begin inspected */
2453
2482
    }
2454
2483
 
2455
2484
    /*
2456
 
      CHECK TABLE command is only command where VIEW allowed here and this
 
2485
      CHECK Table command is only command where VIEW allowed here and this
2457
2486
      command use only temporary teble method for VIEWs resolving => there
2458
2487
      can't be VIEW tree substitition of join view => if opening table
2459
 
      succeed then table->table will have real TABLE pointer as value (in
 
2488
      succeed then table->table will have real Table pointer as value (in
2460
2489
      case of join view substitution table->table can be 0, but here it is
2461
2490
      impossible)
2462
2491
    */
2463
2492
    if (!table->table)
2464
2493
    {
2465
 
      if (!thd->warn_list.elements)
2466
 
        push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2494
      if (!session->warn_list.elements)
 
2495
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
2467
2496
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2468
2497
      goto send_result;
2469
2498
    }
2472
2501
    {
2473
2502
      /* purecov: begin inspected */
2474
2503
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
2475
 
      uint length;
 
2504
      uint32_t length;
2476
2505
      protocol->prepare_for_resend();
2477
2506
      protocol->store(table_name, system_charset_info);
2478
2507
      protocol->store(operator_name, system_charset_info);
2480
2509
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2481
2510
                       table_name);
2482
2511
      protocol->store(buff, length, system_charset_info);
2483
 
      ha_autocommit_or_rollback(thd, 0);
2484
 
      end_trans(thd, COMMIT);
2485
 
      close_thread_tables(thd);
 
2512
      ha_autocommit_or_rollback(session, 0);
 
2513
      end_trans(session, COMMIT);
 
2514
      close_thread_tables(session);
2486
2515
      lex->reset_query_tables_list(false);
2487
2516
      table->table=0;                           // For query cache
2488
2517
      if (protocol->write())
2495
2524
    if (lock_type == TL_WRITE && table->table->s->version)
2496
2525
    {
2497
2526
      pthread_mutex_lock(&LOCK_open);
2498
 
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
 
2527
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2499
2528
                                              "Waiting to get writelock");
2500
 
      mysql_lock_abort(thd,table->table, true);
2501
 
      remove_table_from_cache(thd, table->table->s->db.str,
 
2529
      mysql_lock_abort(session,table->table, true);
 
2530
      remove_table_from_cache(session, table->table->s->db.str,
2502
2531
                              table->table->s->table_name.str,
2503
2532
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2504
2533
                              RTFC_CHECK_KILLED_FLAG);
2505
 
      thd->exit_cond(old_message);
2506
 
      if (thd->killed)
 
2534
      session->exit_cond(old_message);
 
2535
      if (session->killed)
2507
2536
        goto err;
2508
2537
      open_for_modify= 0;
2509
2538
    }
2522
2551
      /* purecov: end */
2523
2552
    }
2524
2553
 
2525
 
    if (operator_func == &handler::ha_repair &&
2526
 
        !(check_opt->sql_flags & TT_USEFRM))
 
2554
    if (operator_func == &handler::ha_repair && !(check_opt->use_frm))
2527
2555
    {
2528
2556
      if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
2529
2557
          (table->table->file->ha_check_for_upgrade(check_opt) ==
2530
2558
           HA_ADMIN_NEEDS_ALTER))
2531
2559
      {
2532
 
        ha_autocommit_or_rollback(thd, 1);
2533
 
        close_thread_tables(thd);
2534
 
        tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2535
 
        result_code= mysql_recreate_table(thd, table);
2536
 
        reenable_binlog(thd);
 
2560
        ha_autocommit_or_rollback(session, 1);
 
2561
        close_thread_tables(session);
 
2562
        result_code= mysql_recreate_table(session, table);
2537
2563
        /*
2538
2564
          mysql_recreate_table() can push OK or ERROR.
2539
2565
          Clear 'OK' status. If there is an error, keep it:
2540
 
          we will store the error message in a result set row 
 
2566
          we will store the error message in a result set row
2541
2567
          and then clear.
2542
2568
        */
2543
 
        if (thd->main_da.is_ok())
2544
 
          thd->main_da.reset_diagnostics_area();
 
2569
        if (session->main_da.is_ok())
 
2570
          session->main_da.reset_diagnostics_area();
2545
2571
        goto send_result;
2546
2572
      }
2547
2573
    }
2548
2574
 
2549
 
    result_code = (table->table->file->*operator_func)(thd, check_opt);
 
2575
    result_code = (table->table->file->*operator_func)(session, check_opt);
2550
2576
 
2551
2577
send_result:
2552
2578
 
2553
2579
    lex->cleanup_after_one_table_open();
2554
 
    thd->clear_error();  // these errors shouldn't get client
 
2580
    session->clear_error();  // these errors shouldn't get client
2555
2581
    {
2556
 
      List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
2582
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2557
2583
      DRIZZLE_ERROR *err;
2558
2584
      while ((err= it++))
2559
2585
      {
2567
2593
        if (protocol->write())
2568
2594
          goto err;
2569
2595
      }
2570
 
      drizzle_reset_errors(thd, true);
 
2596
      drizzle_reset_errors(session, true);
2571
2597
    }
2572
2598
    protocol->prepare_for_resend();
2573
2599
    protocol->store(table_name, system_charset_info);
2579
2605
    case HA_ADMIN_NOT_IMPLEMENTED:
2580
2606
      {
2581
2607
        char buf[ERRMSGSIZE+20];
2582
 
        uint length=snprintf(buf, ERRMSGSIZE,
 
2608
        uint32_t length=snprintf(buf, ERRMSGSIZE,
2583
2609
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
2584
2610
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2585
2611
        protocol->store(buf, length, system_charset_info);
2586
2612
      }
2587
2613
      break;
2588
2614
 
2589
 
    case HA_ADMIN_NOT_BASE_TABLE:
2590
 
      {
2591
 
        char buf[ERRMSGSIZE+20];
2592
 
        uint length= snprintf(buf, ERRMSGSIZE,
2593
 
                              ER(ER_BAD_TABLE_ERROR), table_name);
2594
 
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2595
 
        protocol->store(buf, length, system_charset_info);
2596
 
      }
2597
 
      break;
2598
 
 
2599
2615
    case HA_ADMIN_OK:
2600
2616
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
2601
2617
      protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
2636
2652
    {
2637
2653
      /*
2638
2654
        This is currently used only by InnoDB. ha_innobase::optimize() answers
2639
 
        "try with alter", so here we close the table, do an ALTER TABLE,
 
2655
        "try with alter", so here we close the table, do an ALTER Table,
2640
2656
        reopen the table and do ha_innobase::analyze() on it.
2641
2657
      */
2642
 
      ha_autocommit_or_rollback(thd, 0);
2643
 
      close_thread_tables(thd);
2644
 
      TABLE_LIST *save_next_local= table->next_local,
 
2658
      ha_autocommit_or_rollback(session, 0);
 
2659
      close_thread_tables(session);
 
2660
      TableList *save_next_local= table->next_local,
2645
2661
                 *save_next_global= table->next_global;
2646
2662
      table->next_local= table->next_global= 0;
2647
 
      tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2648
 
      result_code= mysql_recreate_table(thd, table);
2649
 
      reenable_binlog(thd);
 
2663
      result_code= mysql_recreate_table(session, table);
2650
2664
      /*
2651
2665
        mysql_recreate_table() can push OK or ERROR.
2652
2666
        Clear 'OK' status. If there is an error, keep it:
2653
 
        we will store the error message in a result set row 
 
2667
        we will store the error message in a result set row
2654
2668
        and then clear.
2655
2669
      */
2656
 
      if (thd->main_da.is_ok())
2657
 
        thd->main_da.reset_diagnostics_area();
2658
 
      ha_autocommit_or_rollback(thd, 0);
2659
 
      close_thread_tables(thd);
 
2670
      if (session->main_da.is_ok())
 
2671
        session->main_da.reset_diagnostics_area();
 
2672
      ha_autocommit_or_rollback(session, 0);
 
2673
      close_thread_tables(session);
2660
2674
      if (!result_code) // recreation went ok
2661
2675
      {
2662
 
        if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
2663
 
            ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
 
2676
        if ((table->table= open_ltable(session, table, lock_type, 0)) &&
 
2677
            ((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2664
2678
          result_code= 0; // analyze went ok
2665
2679
      }
2666
2680
      if (result_code) // either mysql_recreate_table or analyze failed
2667
2681
      {
2668
 
        assert(thd->is_error());
2669
 
        if (thd->is_error())
 
2682
        assert(session->is_error());
 
2683
        if (session->is_error())
2670
2684
        {
2671
 
          const char *err_msg= thd->main_da.message();
2672
 
          if (!thd->vio_ok())
 
2685
          const char *err_msg= session->main_da.message();
 
2686
          if (!session->vio_ok())
2673
2687
          {
2674
 
            sql_print_error(err_msg);
 
2688
            errmsg_printf(ERRMSG_LVL_ERROR, "%s", err_msg);
2675
2689
          }
2676
2690
          else
2677
2691
          {
2684
2698
            protocol->store(table_name, system_charset_info);
2685
2699
            protocol->store(operator_name, system_charset_info);
2686
2700
          }
2687
 
          thd->clear_error();
 
2701
          session->clear_error();
2688
2702
        }
2689
2703
      }
2690
2704
      result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
2692
2706
      table->next_global= save_next_global;
2693
2707
      goto send_result_message;
2694
2708
    }
2695
 
    case HA_ADMIN_WRONG_CHECKSUM:
2696
 
    {
2697
 
      protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2698
 
      protocol->store(ER(ER_VIEW_CHECKSUM), strlen(ER(ER_VIEW_CHECKSUM)),
2699
 
                      system_charset_info);
2700
 
      break;
2701
 
    }
2702
 
 
2703
2709
    case HA_ADMIN_NEEDS_UPGRADE:
2704
2710
    case HA_ADMIN_NEEDS_ALTER:
2705
2711
    {
2706
2712
      char buf[ERRMSGSIZE];
2707
 
      uint length;
 
2713
      uint32_t length;
2708
2714
 
2709
2715
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2710
2716
      length=snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
2716
2722
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
2717
2723
      {
2718
2724
        char buf[ERRMSGSIZE+20];
2719
 
        uint length=snprintf(buf, ERRMSGSIZE,
2720
 
                             "Unknown - internal error %d during operation",
 
2725
        uint32_t length=snprintf(buf, ERRMSGSIZE,
 
2726
                             _("Unknown - internal error %d during operation"),
2721
2727
                             result_code);
2722
2728
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2723
2729
        protocol->store(buf, length, system_charset_info);
2736
2742
        else
2737
2743
        {
2738
2744
          pthread_mutex_lock(&LOCK_open);
2739
 
          remove_table_from_cache(thd, table->table->s->db.str,
 
2745
          remove_table_from_cache(session, table->table->s->db.str,
2740
2746
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
2741
2747
          pthread_mutex_unlock(&LOCK_open);
2742
2748
        }
2743
2749
      }
2744
2750
    }
2745
 
    ha_autocommit_or_rollback(thd, 0);
2746
 
    end_trans(thd, COMMIT);
2747
 
    close_thread_tables(thd);
 
2751
    ha_autocommit_or_rollback(session, 0);
 
2752
    end_trans(session, COMMIT);
 
2753
    close_thread_tables(session);
2748
2754
    table->table=0;                             // For query cache
2749
2755
    if (protocol->write())
2750
2756
      goto err;
2751
2757
  }
2752
2758
 
2753
 
  my_eof(thd);
 
2759
  session->my_eof();
2754
2760
  return(false);
2755
2761
 
2756
2762
err:
2757
 
  ha_autocommit_or_rollback(thd, 1);
2758
 
  end_trans(thd, ROLLBACK);
2759
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
2763
  ha_autocommit_or_rollback(session, 1);
 
2764
  end_trans(session, ROLLBACK);
 
2765
  close_thread_tables(session);                 // Shouldn't be needed
2760
2766
  if (table)
2761
2767
    table->table=0;
2762
2768
  return(true);
2763
2769
}
2764
2770
 
2765
2771
 
2766
 
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
2772
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2767
2773
{
2768
 
  return(mysql_admin_table(thd, tables, check_opt,
2769
 
                                "repair", TL_WRITE, 1,
2770
 
                                test(check_opt->sql_flags & TT_USEFRM),
2771
 
                                HA_OPEN_FOR_REPAIR,
2772
 
                                &prepare_for_repair,
2773
 
                                &handler::ha_repair));
 
2774
  return(mysql_admin_table(session, tables, check_opt,
 
2775
                           "repair", TL_WRITE, 1,
 
2776
                           check_opt->use_frm,
 
2777
                           HA_OPEN_FOR_REPAIR,
 
2778
                           &prepare_for_repair,
 
2779
                           &handler::ha_repair));
2774
2780
}
2775
2781
 
2776
2782
 
2777
 
bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
2783
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2778
2784
{
2779
 
  return(mysql_admin_table(thd, tables, check_opt,
2780
 
                                "optimize", TL_WRITE, 1,0,0,0,
2781
 
                                &handler::ha_optimize));
 
2785
  return(mysql_admin_table(session, tables, check_opt,
 
2786
                           "optimize", TL_WRITE, 1,0,0,0,
 
2787
                           &handler::ha_optimize));
2782
2788
}
2783
2789
 
2784
2790
 
2787
2793
 
2788
2794
  SYNOPSIS
2789
2795
    mysql_assign_to_keycache()
2790
 
    thd         Thread object
 
2796
    session             Thread object
2791
2797
    tables      Table list (one table only)
2792
2798
 
2793
2799
  RETURN VALUES
2795
2801
   true  error
2796
2802
*/
2797
2803
 
2798
 
bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
 
2804
bool mysql_assign_to_keycache(Session* session, TableList* tables,
2799
2805
                             LEX_STRING *key_cache_name)
2800
2806
{
2801
2807
  HA_CHECK_OPT check_opt;
2811
2817
  }
2812
2818
  pthread_mutex_unlock(&LOCK_global_system_variables);
2813
2819
  check_opt.key_cache= key_cache;
2814
 
  return(mysql_admin_table(thd, tables, &check_opt,
 
2820
  return(mysql_admin_table(session, tables, &check_opt,
2815
2821
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
2816
2822
                                0, 0, &handler::assign_to_keycache));
2817
2823
}
2822
2828
 
2823
2829
  SYNOPSIS
2824
2830
    reassign_keycache_tables()
2825
 
    thd         Thread object
 
2831
    session             Thread object
2826
2832
    src_cache   Reference to the key cache to clean up
2827
2833
    dest_cache  New key cache
2828
2834
 
2842
2848
    0     ok
2843
2849
*/
2844
2850
 
2845
 
int reassign_keycache_tables(THD *thd __attribute__((unused)),
 
2851
int reassign_keycache_tables(Session *,
2846
2852
                             KEY_CACHE *src_cache,
2847
2853
                             KEY_CACHE *dst_cache)
2848
2854
{
2857
2863
/**
2858
2864
  @brief          Create frm file based on I_S table
2859
2865
 
2860
 
  @param[in]      thd                      thread handler
2861
 
  @param[in]      schema_table             I_S table           
 
2866
  @param[in]      session                      thread handler
 
2867
  @param[in]      schema_table             I_S table
2862
2868
  @param[in]      dst_path                 path where frm should be created
2863
2869
  @param[in]      create_info              Create info
2864
2870
 
2866
2872
    @retval       0                        success
2867
2873
    @retval       1                        error
2868
2874
*/
2869
 
bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
 
2875
bool mysql_create_like_schema_frm(Session* session, TableList* schema_table,
2870
2876
                                  char *dst_path, HA_CREATE_INFO *create_info)
2871
2877
{
2872
2878
  HA_CREATE_INFO local_create_info;
2873
2879
  Alter_info alter_info;
2874
2880
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
2875
 
  uint keys= schema_table->table->s->keys;
2876
 
  uint db_options= 0;
 
2881
  uint32_t keys= schema_table->table->s->keys;
 
2882
  uint32_t db_options= 0;
2877
2883
 
2878
2884
  memset(&local_create_info, 0, sizeof(local_create_info));
2879
2885
  local_create_info.db_type= schema_table->table->s->db_type();
2881
2887
  local_create_info.default_table_charset=default_charset_info;
2882
2888
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2883
2889
  schema_table->table->use_all_columns();
2884
 
  if (mysql_prepare_alter_table(thd, schema_table->table,
 
2890
  if (mysql_prepare_alter_table(session, schema_table->table,
2885
2891
                                &local_create_info, &alter_info))
2886
 
    return(1);
2887
 
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
 
2892
    return true;
 
2893
 
 
2894
  if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2888
2895
                                 tmp_table, &db_options,
2889
2896
                                 schema_table->table->file,
2890
2897
                                 &schema_table->table->s->key_info, &keys, 0))
2891
 
    return(1);
 
2898
    return true;
 
2899
 
2892
2900
  local_create_info.max_rows= 0;
2893
 
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
 
2901
  if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
2894
2902
                       &local_create_info, alter_info.create_list,
2895
2903
                       keys, schema_table->table->s->key_info,
2896
 
                       schema_table->table->file))
2897
 
    return(1);
2898
 
  return(0);
 
2904
                       schema_table->table->file, true))
 
2905
    return true;
 
2906
 
 
2907
  return false;
2899
2908
}
2900
2909
 
2901
 
 
2902
2910
/*
2903
2911
  Create a table identical to the specified table
2904
2912
 
2905
2913
  SYNOPSIS
2906
2914
    mysql_create_like_table()
2907
 
    thd         Thread object
 
2915
    session             Thread object
2908
2916
    table       Table list element for target table
2909
2917
    src_table   Table list element for source table
2910
2918
    create_info Create info
2914
2922
    true  error
2915
2923
*/
2916
2924
 
2917
 
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
 
2925
bool mysql_create_like_table(Session* session, TableList* table, TableList* src_table,
2918
2926
                             HA_CREATE_INFO *create_info)
2919
2927
{
2920
 
  TABLE *name_lock= 0;
 
2928
  Table *name_lock= 0;
2921
2929
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
2922
 
  uint dst_path_length;
 
2930
  uint32_t dst_path_length;
2923
2931
  char *db= table->db;
2924
2932
  char *table_name= table->table_name;
2925
2933
  int  err;
2926
2934
  bool res= true;
2927
 
  uint not_used;
2928
 
 
2929
 
 
2930
 
  /* CREATE TABLE ... LIKE is not allowed for views. */
2931
 
  src_table->required_type= FRMTYPE_TABLE;
 
2935
  uint32_t not_used;
2932
2936
 
2933
2937
  /*
2934
2938
    By opening source table we guarantee that it exists and no concurrent
2939
2943
    we ensure that our statement is properly isolated from all concurrent
2940
2944
    operations which matter.
2941
2945
  */
2942
 
  if (open_tables(thd, &src_table, &not_used, 0))
 
2946
  if (open_tables(session, &src_table, &not_used, 0))
2943
2947
    return(true);
2944
2948
 
2945
 
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
 
2949
  sprintf(src_path,"%s%s",src_table->table->s->path.str, reg_ext);
2946
2950
 
2947
 
  /* 
 
2951
  /*
2948
2952
    Check that destination tables does not exist. Note that its name
2949
2953
    was already checked when it was added to the table list.
2950
2954
  */
2951
2955
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2952
2956
  {
2953
 
    if (find_temporary_table(thd, db, table_name))
 
2957
    if (find_temporary_table(session, db, table_name))
2954
2958
      goto table_exists;
2955
 
    dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
 
2959
    dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2956
2960
    create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2957
2961
  }
2958
2962
  else
2959
2963
  {
2960
 
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
 
2964
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2961
2965
      goto err;
2962
2966
    if (!name_lock)
2963
2967
      goto table_exists;
2980
2984
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2981
2985
    during the call to ha_create_table(). See bug #28614 for more info.
2982
2986
  */
2983
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
2987
  pthread_mutex_lock(&LOCK_open);
2984
2988
  if (src_table->schema_table)
2985
2989
  {
2986
 
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
 
2990
    if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
2987
2991
    {
2988
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
2992
      pthread_mutex_unlock(&LOCK_open);
2989
2993
      goto err;
2990
2994
    }
2991
2995
  }
2992
 
  else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
 
2996
  else
2993
2997
  {
2994
 
    if (my_errno == ENOENT)
2995
 
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2996
 
    else
2997
 
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2998
 
    VOID(pthread_mutex_unlock(&LOCK_open));
2999
 
    goto err;
 
2998
    int frmcopyr= my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE));
 
2999
 
 
3000
    string dfesrc(src_path);
 
3001
    string dfedst(dst_path);
 
3002
 
 
3003
    dfesrc.replace(dfesrc.find(".frm"), 4, ".dfe" );
 
3004
    dfedst.replace(dfedst.find(".frm"), 4, ".dfe" );
 
3005
 
 
3006
    int dfecopyr= my_copy(dfesrc.c_str(), dfedst.c_str(),
 
3007
                          MYF(MY_DONT_OVERWRITE_FILE));
 
3008
 
 
3009
    if(frmcopyr || dfecopyr) // FIXME: should handle only one fail.
 
3010
    {
 
3011
      if (my_errno == ENOENT)
 
3012
        my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
3013
      else
 
3014
        my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
 
3015
      pthread_mutex_unlock(&LOCK_open);
 
3016
      goto err;
 
3017
    }
3000
3018
  }
3001
3019
 
3002
3020
  /*
3005
3023
    and temporary tables).
3006
3024
  */
3007
3025
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
3008
 
  if (thd->variables.keep_files_on_create)
 
3026
  if (session->variables.keep_files_on_create)
3009
3027
    create_info->options|= HA_CREATE_KEEP_FILES;
3010
 
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
3011
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3028
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
 
3029
  pthread_mutex_unlock(&LOCK_open);
3012
3030
 
3013
3031
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3014
3032
  {
3015
 
    if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
 
3033
    if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3016
3034
                                     OTM_OPEN))
3017
3035
    {
3018
3036
      (void) rm_temporary_table(create_info->db_type,
3019
 
                                dst_path, false); /* purecov: inspected */
 
3037
                                dst_path);
3020
3038
      goto err;     /* purecov: inspected */
3021
3039
    }
3022
3040
  }
3030
3048
  /*
3031
3049
    We have to write the query before we unlock the tables.
3032
3050
  */
3033
 
  if (thd->current_stmt_binlog_row_based)
3034
3051
  {
3035
3052
    /*
3036
3053
       Since temporary tables are not replicated under row-based
3063
3080
          of this function.
3064
3081
        */
3065
3082
        table->table= name_lock;
3066
 
        VOID(pthread_mutex_lock(&LOCK_open));
3067
 
        if (reopen_name_locked_table(thd, table, false))
 
3083
        pthread_mutex_lock(&LOCK_open);
 
3084
        if (reopen_name_locked_table(session, table, false))
3068
3085
        {
3069
 
          VOID(pthread_mutex_unlock(&LOCK_open));
 
3086
          pthread_mutex_unlock(&LOCK_open);
3070
3087
          goto err;
3071
3088
        }
3072
 
        VOID(pthread_mutex_unlock(&LOCK_open));
 
3089
        pthread_mutex_unlock(&LOCK_open);
3073
3090
 
3074
 
        int result= store_create_info(thd, table, &query,
 
3091
        int result= store_create_info(session, table, &query,
3075
3092
                                               create_info);
3076
3093
 
3077
3094
        assert(result == 0); // store_create_info() always return 0
3078
 
        write_bin_log(thd, true, query.ptr(), query.length());
 
3095
        write_bin_log(session, true, query.ptr(), query.length());
3079
3096
      }
3080
3097
      else                                      // Case 1
3081
 
        write_bin_log(thd, true, thd->query, thd->query_length);
 
3098
        write_bin_log(session, true, session->query, session->query_length);
3082
3099
    }
3083
3100
    /*
3084
3101
      Case 3 and 4 does nothing under RBR
3085
3102
    */
3086
3103
  }
3087
 
  else
3088
 
    write_bin_log(thd, true, thd->query, thd->query_length);
3089
3104
 
3090
3105
  res= false;
3091
3106
  goto err;
3096
3111
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
3097
3112
    snprintf(warn_buff, sizeof(warn_buff),
3098
3113
             ER(ER_TABLE_EXISTS_ERROR), table_name);
3099
 
    push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3114
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3100
3115
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3101
3116
    res= false;
3102
3117
  }
3107
3122
  if (name_lock)
3108
3123
  {
3109
3124
    pthread_mutex_lock(&LOCK_open);
3110
 
    unlink_open_table(thd, name_lock, false);
 
3125
    unlink_open_table(session, name_lock, false);
3111
3126
    pthread_mutex_unlock(&LOCK_open);
3112
3127
  }
3113
3128
  return(res);
3114
3129
}
3115
3130
 
3116
3131
 
3117
 
bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
 
3132
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3118
3133
{
3119
3134
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3120
3135
 
3121
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3136
  return(mysql_admin_table(session, tables, check_opt,
3122
3137
                                "analyze", lock_type, 1, 0, 0, 0,
3123
3138
                                &handler::ha_analyze));
3124
3139
}
3125
3140
 
3126
3141
 
3127
 
bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
 
3142
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3128
3143
{
3129
3144
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3130
3145
 
3131
 
  return(mysql_admin_table(thd, tables, check_opt,
 
3146
  return(mysql_admin_table(session, tables, check_opt,
3132
3147
                                "check", lock_type,
3133
3148
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
3134
3149
                                &handler::ha_check));
3137
3152
 
3138
3153
/* table_list should contain just one table */
3139
3154
static int
3140
 
mysql_discard_or_import_tablespace(THD *thd,
3141
 
                                   TABLE_LIST *table_list,
 
3155
mysql_discard_or_import_tablespace(Session *session,
 
3156
                                   TableList *table_list,
3142
3157
                                   enum tablespace_op_type tablespace_op)
3143
3158
{
3144
 
  TABLE *table;
 
3159
  Table *table;
3145
3160
  bool discard;
3146
3161
  int error;
3147
3162
 
3148
3163
  /*
3149
3164
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
3150
 
    ALTER TABLE
 
3165
    ALTER Table
3151
3166
  */
3152
3167
 
3153
 
  thd_proc_info(thd, "discard_or_import_tablespace");
 
3168
  session->set_proc_info("discard_or_import_tablespace");
3154
3169
 
3155
3170
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3156
3171
 
3158
3173
   We set this flag so that ha_innobase::open and ::external_lock() do
3159
3174
   not complain when we lock the table
3160
3175
 */
3161
 
  thd->tablespace_op= true;
3162
 
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
 
3176
  session->tablespace_op= true;
 
3177
  if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3163
3178
  {
3164
 
    thd->tablespace_op=false;
 
3179
    session->tablespace_op=false;
3165
3180
    return(-1);
3166
3181
  }
3167
3182
 
3168
3183
  error= table->file->ha_discard_or_import_tablespace(discard);
3169
3184
 
3170
 
  thd_proc_info(thd, "end");
 
3185
  session->set_proc_info("end");
3171
3186
 
3172
3187
  if (error)
3173
3188
    goto err;
3174
3189
 
3175
 
  /* The ALTER TABLE is always in its own transaction */
3176
 
  error = ha_autocommit_or_rollback(thd, 0);
3177
 
  if (end_active_trans(thd))
 
3190
  /* The ALTER Table is always in its own transaction */
 
3191
  error = ha_autocommit_or_rollback(session, 0);
 
3192
  if (end_active_trans(session))
3178
3193
    error=1;
3179
3194
  if (error)
3180
3195
    goto err;
3181
 
  write_bin_log(thd, false, thd->query, thd->query_length);
 
3196
  write_bin_log(session, false, session->query, session->query_length);
3182
3197
 
3183
3198
err:
3184
 
  ha_autocommit_or_rollback(thd, error);
3185
 
  thd->tablespace_op=false;
3186
 
  
 
3199
  ha_autocommit_or_rollback(session, error);
 
3200
  session->tablespace_op=false;
 
3201
 
3187
3202
  if (error == 0)
3188
3203
  {
3189
 
    my_ok(thd);
 
3204
    session->my_ok();
3190
3205
    return(0);
3191
3206
  }
3192
3207
 
3193
3208
  table->file->print_error(error, MYF(0));
3194
 
    
 
3209
 
3195
3210
  return(-1);
3196
3211
}
3197
3212
 
3201
3216
 
3202
3217
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
3203
3218
{
3204
 
  uint flags= alter_info->flags;
 
3219
  uint32_t flags= alter_info->flags;
3205
3220
 
3206
3221
  if (ALTER_ADD_COLUMN & flags)
3207
3222
    *alter_flags|= HA_ADD_COLUMN;
3231
3246
 
3232
3247
 
3233
3248
/**
3234
 
   @param       thd                Thread
 
3249
   @param       session                Thread
3235
3250
   @param       table              The original table.
3236
3251
   @param       alter_info         Alter options, fields and keys for the new
3237
3252
                                   table.
3246
3261
   table has in arguments create_list, key_list and create_info.
3247
3262
 
3248
3263
   By comparing the changes between the original and new table
3249
 
   we can determine how much it has changed after ALTER TABLE
 
3264
   we can determine how much it has changed after ALTER Table
3250
3265
   and whether we need to make a copy of the table, or just change
3251
3266
   the .frm file.
3252
3267
 
3263
3278
 
3264
3279
static
3265
3280
bool
3266
 
compare_tables(THD *thd,
3267
 
               TABLE *table,
 
3281
compare_tables(Session *session,
 
3282
               Table *table,
3268
3283
               Alter_info *alter_info,
3269
 
                           HA_CREATE_INFO *create_info,
3270
 
               uint order_num,
 
3284
               HA_CREATE_INFO *create_info,
 
3285
               uint32_t order_num,
3271
3286
               HA_ALTER_FLAGS *alter_flags,
3272
3287
               HA_ALTER_INFO *ha_alter_info,
3273
 
               uint *table_changes)
 
3288
               uint32_t *table_changes)
3274
3289
{
3275
3290
  Field **f_ptr, *field;
3276
 
  uint table_changes_local= 0;
 
3291
  uint32_t table_changes_local= 0;
3277
3292
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
3278
3293
  Create_field *new_field;
3279
3294
  KEY_PART_INFO *key_part;
3280
3295
  KEY_PART_INFO *end;
3281
 
  /*
3282
 
    Remember if the new definition has new VARCHAR column;
3283
 
    create_info->varchar will be reset in mysql_prepare_create_table.
3284
 
  */
3285
 
  bool varchar= create_info->varchar;
3286
3296
 
3287
3297
  {
3288
3298
    /*
3297
3307
      like to keep compare_tables() idempotent (not altering any
3298
3308
      of the arguments) we create a copy of alter_info here and
3299
3309
      pass it to mysql_prepare_create_table, then use the result
3300
 
      to evaluate possibility of fast ALTER TABLE, and then
 
3310
      to evaluate possibility of fast ALTER Table, and then
3301
3311
      destroy the copy.
3302
3312
    */
3303
 
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
3304
 
    THD *thd= table->in_use;
3305
 
    uint db_options= 0; /* not used */
 
3313
    Alter_info tmp_alter_info(*alter_info, session->mem_root);
 
3314
    session= table->in_use;
 
3315
    uint32_t db_options= 0; /* not used */
3306
3316
    /* Create the prepared information. */
3307
 
    if (mysql_prepare_create_table(thd, create_info,
 
3317
    if (mysql_prepare_create_table(session, create_info,
3308
3318
                                   &tmp_alter_info,
3309
3319
                                   (table->s->tmp_table != NO_TMP_TABLE),
3310
3320
                                   &db_options,
3315
3325
      return(true);
3316
3326
    /* Allocate result buffers. */
3317
3327
    if (! (ha_alter_info->index_drop_buffer=
3318
 
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
 
3328
           (uint*) session->alloc(sizeof(uint) * table->s->keys)) ||
3319
3329
        ! (ha_alter_info->index_add_buffer=
3320
 
           (uint*) thd->alloc(sizeof(uint) *
 
3330
           (uint*) session->alloc(sizeof(uint) *
3321
3331
                              tmp_alter_info.key_list.elements)))
3322
3332
      return(true);
3323
3333
  }
3330
3340
 
3331
3341
  /*
3332
3342
    Some very basic checks. If number of fields changes, or the
3333
 
    handler, we need to run full ALTER TABLE. In the future
 
3343
    handler, we need to run full ALTER Table. In the future
3334
3344
    new fields can be added and old dropped without copy, but
3335
3345
    not yet.
3336
3346
 
3337
 
    Test also that engine was not given during ALTER TABLE, or
 
3347
    Test also that engine was not given during ALTER Table, or
3338
3348
    we are force to run regular alter table (copy).
3339
 
    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
 
3349
    E.g. ALTER Table tbl_name ENGINE=MyISAM.
3340
3350
 
3341
3351
    For the following ones we also want to run regular alter table:
3342
 
    ALTER TABLE tbl_name ORDER BY ..
3343
 
    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
 
3352
    ALTER Table tbl_name order_st BY ..
 
3353
    ALTER Table tbl_name CONVERT TO CHARACTER SET ..
3344
3354
 
3345
3355
    At the moment we can't handle altering temporary tables without a copy.
3346
 
    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
 
3356
    We also test if OPTIMIZE Table was given and was mapped to alter table.
3347
3357
    In that case we always do full copy.
3348
3358
 
3349
3359
    There was a bug prior to mysql-4.0.25. Number of null fields was
3363
3373
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3364
3374
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3365
3375
      order_num ||
3366
 
      !table->s->mysql_version ||
3367
 
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
 
3376
      !table->s->mysql_version)
3368
3377
  {
3369
3378
    *table_changes= IS_EQUAL_NO;
3370
3379
    /*
3386
3395
    /* TODO check for ADD/DROP FOREIGN KEY */
3387
3396
    if (alter_info->flags & ALTER_FOREIGN_KEY)
3388
3397
      *alter_flags|=  HA_ALTER_FOREIGN_KEY;
3389
 
    if (!table->s->mysql_version ||
3390
 
        (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
3391
 
      *alter_flags|=  HA_ALTER_COLUMN_TYPE;
3392
3398
  }
3393
3399
  /*
3394
3400
    Go through fields and check if the original ones are compatible
3415
3421
      if (!(table_changes_local= field->is_equal(new_field)))
3416
3422
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3417
3423
 
 
3424
      /*
 
3425
        Check if the altered column is a stored virtual field.
 
3426
        TODO: Mark such a column with an alter flag only if
 
3427
        the expression functions are not equal.
 
3428
      */
 
3429
      if (field->is_stored && field->vcol_info)
 
3430
        *alter_flags|= HA_ALTER_STORED_VCOL;
 
3431
 
3418
3432
      /* Check if field was renamed */
3419
3433
      field->flags&= ~FIELD_IS_RENAMED;
3420
3434
      if (my_strcasecmp(system_charset_info,
3480
3494
      if (table_key->flags & HA_NOSAME)
3481
3495
      {
3482
3496
        /* Unique key. Check for "PRIMARY". */
3483
 
        if (! my_strcasecmp(system_charset_info,
3484
 
                            table_key->name, primary_key_name))
 
3497
        if (is_primary_key(table_key))
3485
3498
          *alter_flags|= HA_DROP_PK_INDEX;
3486
3499
        else
3487
3500
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
3501
3514
      if (table_key->flags & HA_NOSAME)
3502
3515
      {
3503
3516
        // Unique key. Check for "PRIMARY".
3504
 
        if (! my_strcasecmp(system_charset_info,
3505
 
                            table_key->name, primary_key_name))
 
3517
        if (is_primary_key(table_key))
3506
3518
          *alter_flags|= HA_ALTER_PK_INDEX;
3507
3519
        else
3508
3520
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3531
3543
        if (table_key->flags & HA_NOSAME)
3532
3544
        {
3533
3545
          /* Unique key. Check for "PRIMARY" */
3534
 
          if (! my_strcasecmp(system_charset_info,
3535
 
                              table_key->name, primary_key_name))
 
3546
          if (is_primary_key(table_key))
3536
3547
            *alter_flags|= HA_ALTER_PK_INDEX;
3537
3548
          else
3538
3549
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3594
3605
      if (new_key->flags & HA_NOSAME)
3595
3606
      {
3596
3607
        /* Unique key. Check for "PRIMARY" */
3597
 
        if (! my_strcasecmp(system_charset_info,
3598
 
                            new_key->name, primary_key_name))
 
3608
        if (is_primary_key(new_key))
3599
3609
          *alter_flags|= HA_ADD_PK_INDEX;
3600
3610
        else
3601
3611
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
3611
3621
 
3612
3622
 
3613
3623
/*
3614
 
  Manages enabling/disabling of indexes for ALTER TABLE
 
3624
  Manages enabling/disabling of indexes for ALTER Table
3615
3625
 
3616
3626
  SYNOPSIS
3617
3627
    alter_table_manage_keys()
3626
3636
*/
3627
3637
 
3628
3638
static
3629
 
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
 
3639
bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
3630
3640
                             enum enum_enable_or_disable keys_onoff)
3631
3641
{
3632
3642
  int error= 0;
3644
3654
 
3645
3655
  if (error == HA_ERR_WRONG_COMMAND)
3646
3656
  {
3647
 
    push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
3657
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
3648
3658
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3649
3659
                        table->s->table_name.str);
3650
3660
    error= 0;
3654
3664
  return(error);
3655
3665
}
3656
3666
 
3657
 
int create_temporary_table(THD *thd,
3658
 
                           TABLE *table,
 
3667
int create_temporary_table(Session *session,
 
3668
                           Table *table,
3659
3669
                           char *new_db,
3660
3670
                           char *tmp_name,
3661
3671
                           HA_CREATE_INFO *create_info,
3696
3706
    if (create_info->index_file_name)
3697
3707
    {
3698
3708
      /* Fix index_file_name to have 'tmp_name' as basename */
3699
 
      stpcpy(index_file, tmp_name);
 
3709
      strcpy(index_file, tmp_name);
3700
3710
      create_info->index_file_name=fn_same(index_file,
3701
3711
                                           create_info->index_file_name,
3702
3712
                                           1);
3704
3714
    if (create_info->data_file_name)
3705
3715
    {
3706
3716
      /* Fix data_file_name to have 'tmp_name' as basename */
3707
 
      stpcpy(data_file, tmp_name);
 
3717
      strcpy(data_file, tmp_name);
3708
3718
      create_info->data_file_name=fn_same(data_file,
3709
3719
                                          create_info->data_file_name,
3710
3720
                                          1);
3715
3725
 
3716
3726
  /*
3717
3727
    Create a table with a temporary name.
3718
 
    With create_info->frm_only == 1 this creates a .frm file only.
3719
3728
    We don't log the statement, it will be logged later.
3720
3729
  */
3721
 
  tmp_disable_binlog(thd);
3722
 
  error= mysql_create_table(thd, new_db, tmp_name,
 
3730
  error= mysql_create_table(session, new_db, tmp_name,
3723
3731
                            create_info, alter_info, 1, 0);
3724
 
  reenable_binlog(thd);
3725
3732
 
3726
3733
  return(error);
3727
3734
}
3732
3739
 
3733
3740
  SYNOPSIS
3734
3741
    create_altered_table()
3735
 
      thd              Thread handle
 
3742
      session              Thread handle
3736
3743
      table            The original table
3737
3744
      create_info      Information from the parsing phase about new
3738
3745
                       table properties.
3746
3753
    The temporary table is created without storing it in any storage engine
3747
3754
    and is opened only to get the table struct and frm file reference.
3748
3755
*/
3749
 
TABLE *create_altered_table(THD *thd,
3750
 
                            TABLE *table,
 
3756
Table *create_altered_table(Session *session,
 
3757
                            Table *table,
3751
3758
                            char *new_db,
3752
3759
                            HA_CREATE_INFO *create_info,
3753
3760
                            Alter_info *alter_info,
3755
3762
{
3756
3763
  int error;
3757
3764
  HA_CREATE_INFO altered_create_info(*create_info);
3758
 
  TABLE *altered_table;
 
3765
  Table *altered_table;
3759
3766
  char tmp_name[80];
3760
3767
  char path[FN_REFLEN];
3761
3768
 
3762
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3763
 
           tmp_file_prefix, current_pid, thd->thread_id);
 
3769
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
 
3770
           TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3764
3771
  /* Safety fix for InnoDB */
3765
3772
  if (lower_case_table_names)
3766
3773
    my_casedn_str(files_charset_info, tmp_name);
3767
3774
  altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
3768
 
  altered_create_info.frm_only= 1;
3769
 
  if ((error= create_temporary_table(thd, table, new_db, tmp_name,
 
3775
 
 
3776
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
3770
3777
                                     &altered_create_info,
3771
3778
                                     alter_info, db_change)))
3772
3779
  {
3775
3782
 
3776
3783
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
3777
3784
                       FN_IS_TMP);
3778
 
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
 
3785
  altered_table= open_temporary_table(session, path, new_db, tmp_name, 1,
3779
3786
                                      OTM_ALTER);
3780
3787
  return(altered_table);
3781
3788
 
3788
3795
 
3789
3796
  SYNOPSIS
3790
3797
    mysql_fast_or_online_alter_table()
3791
 
      thd              Thread handle
 
3798
      session              Thread handle
3792
3799
      table            The original table
3793
3800
      altered_table    A temporary table showing how we will change table
3794
3801
      create_info      Information from the parsing phase about new
3808
3815
    operation directly, on-line without mysql having to copy
3809
3816
    the table.
3810
3817
*/
3811
 
int mysql_fast_or_online_alter_table(THD *thd,
3812
 
                                     TABLE *table,
3813
 
                                     TABLE *altered_table,
 
3818
int mysql_fast_or_online_alter_table(Session *session,
 
3819
                                     Table *table,
 
3820
                                     Table *altered_table,
3814
3821
                                     HA_CREATE_INFO *create_info,
3815
3822
                                     HA_ALTER_INFO *alter_info,
3816
3823
                                     HA_ALTER_FLAGS *ha_alter_flags,
3818
3825
{
3819
3826
  int error= 0;
3820
3827
  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER)?true:false;
3821
 
  TABLE *t_table;
 
3828
  Table *t_table;
3822
3829
 
3823
3830
  if (online)
3824
3831
  {
3825
3832
   /*
3826
3833
      Tell the handler to prepare for the online alter
3827
3834
    */
3828
 
    if ((error= table->file->alter_table_phase1(thd,
 
3835
    if ((error= table->file->alter_table_phase1(session,
3829
3836
                                                altered_table,
3830
3837
                                                create_info,
3831
3838
                                                alter_info,
3836
3843
 
3837
3844
    /*
3838
3845
       Tell the storage engine to perform the online alter table
3839
 
       TODO: 
 
3846
       TODO:
3840
3847
       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
3841
3848
       we need to wrap the next call with a DDL lock.
3842
3849
     */
3843
 
    if ((error= table->file->alter_table_phase2(thd,
 
3850
    if ((error= table->file->alter_table_phase2(session,
3844
3851
                                                altered_table,
3845
3852
                                                create_info,
3846
3853
                                                alter_info,
3853
3860
    The final .frm file is already created as a temporary file
3854
3861
    and will be renamed to the original table name.
3855
3862
  */
3856
 
  VOID(pthread_mutex_lock(&LOCK_open));
3857
 
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
3863
  pthread_mutex_lock(&LOCK_open);
 
3864
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3858
3865
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3859
3866
                          keys_onoff);
3860
 
  close_data_files_and_morph_locks(thd,
 
3867
  close_data_files_and_morph_locks(session,
3861
3868
                                   table->pos_in_table_list->db,
3862
3869
                                   table->pos_in_table_list->table_name);
3863
3870
  if (mysql_rename_table(NULL,
3867
3874
                         table->s->table_name.str, FN_FROM_IS_TMP))
3868
3875
  {
3869
3876
    error= 1;
3870
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3877
    pthread_mutex_unlock(&LOCK_open);
3871
3878
    goto err;
3872
3879
  }
3873
3880
  broadcast_refresh();
3874
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
3881
  pthread_mutex_unlock(&LOCK_open);
3875
3882
 
3876
3883
  /*
3877
 
    The ALTER TABLE is always in its own transaction.
 
3884
    The ALTER Table is always in its own transaction.
3878
3885
    Commit must not be called while LOCK_open is locked. It could call
3879
3886
    wait_if_global_read_lock(), which could create a deadlock if called
3880
3887
    with LOCK_open.
3881
3888
  */
3882
 
  error= ha_autocommit_or_rollback(thd, 0);
 
3889
  error= ha_autocommit_or_rollback(session, 0);
3883
3890
 
3884
 
  if (ha_commit(thd))
 
3891
  if (ha_commit(session))
3885
3892
    error=1;
3886
3893
  if (error)
3887
3894
    goto err;
3888
3895
  if (online)
3889
3896
  {
3890
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3897
    pthread_mutex_lock(&LOCK_open);
3891
3898
    if (reopen_table(table))
3892
3899
    {
3893
3900
      error= -1;
3894
3901
      goto err;
3895
3902
    }
3896
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3903
    pthread_mutex_unlock(&LOCK_open);
3897
3904
    t_table= table;
3898
3905
 
3899
3906
   /*
3900
3907
      Tell the handler that the changed frm is on disk and table
3901
3908
      has been re-opened
3902
3909
   */
3903
 
    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
 
3910
    if ((error= t_table->file->alter_table_phase3(session, t_table)))
3904
3911
    {
3905
3912
      goto err;
3906
3913
    }
3907
3914
 
3908
3915
    /*
3909
3916
      We are going to reopen table down on the road, so we have to restore
3910
 
      state of the TABLE object which we used for obtaining of handler
 
3917
      state of the Table object which we used for obtaining of handler
3911
3918
      object to make it suitable for reopening.
3912
3919
    */
3913
3920
    assert(t_table == table);
3914
3921
    table->open_placeholder= 1;
3915
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
3922
    pthread_mutex_lock(&LOCK_open);
3916
3923
    close_handle_and_leave_table_as_lock(table);
3917
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3924
    pthread_mutex_unlock(&LOCK_open);
3918
3925
  }
3919
3926
 
3920
3927
 err:
3925
3932
 
3926
3933
 
3927
3934
/**
3928
 
  Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
 
3935
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
3929
3936
 
3930
 
  This function transforms parse output of ALTER TABLE - lists of
 
3937
  This function transforms parse output of ALTER Table - lists of
3931
3938
  columns and keys to add, drop or modify into, essentially,
3932
3939
  CREATE TABLE definition - a list of columns and keys of the new
3933
3940
  table. While doing so, it also performs some (bug not all)
3934
3941
  semantic checks.
3935
3942
 
3936
3943
  This function is invoked when we know that we're going to
3937
 
  perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
 
3944
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
3938
3945
  is not possible, perhaps because the ALTER statement contains
3939
3946
  instructions that require change in table data, not only in
3940
3947
  table definition or indexes.
3941
3948
 
3942
 
  @param[in,out]  thd         thread handle. Used as a memory pool
 
3949
  @param[in,out]  session         thread handle. Used as a memory pool
3943
3950
                              and source of environment information.
3944
3951
  @param[in]      table       the source table, open and locked
3945
3952
                              Used as an interface to the storage engine
3946
3953
                              to acquire additional information about
3947
3954
                              the original table.
3948
 
  @param[in,out]  create_info A blob with CREATE/ALTER TABLE
 
3955
  @param[in,out]  create_info A blob with CREATE/ALTER Table
3949
3956
                              parameters
3950
3957
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
3951
3958
                              Originally create_info was used only in
3952
 
                              CREATE TABLE and alter_info only in ALTER TABLE.
 
3959
                              CREATE TABLE and alter_info only in ALTER Table.
3953
3960
                              But since ALTER might end-up doing CREATE,
3954
3961
                              this distinction is gone and we just carry
3955
3962
                              around two structures.
3961
3968
    Prepares alter_info->create_list and alter_info->key_list with
3962
3969
    columns and keys of the new table.
3963
3970
  @retval true   error, out of memory or a semantical error in ALTER
3964
 
                 TABLE instructions
 
3971
                 Table instructions
3965
3972
  @retval false  success
3966
3973
*/
3967
3974
 
3968
3975
static bool
3969
 
mysql_prepare_alter_table(THD *thd, TABLE *table,
 
3976
mysql_prepare_alter_table(Session *session, Table *table,
3970
3977
                          HA_CREATE_INFO *create_info,
3971
3978
                          Alter_info *alter_info)
3972
3979
{
3981
3988
  List_iterator<Create_field> find_it(new_create_list);
3982
3989
  List_iterator<Create_field> field_it(new_create_list);
3983
3990
  List<Key_part_spec> key_parts;
3984
 
  uint db_create_options= (table->s->db_create_options
 
3991
  uint32_t db_create_options= (table->s->db_create_options
3985
3992
                           & ~(HA_OPTION_PACK_RECORD));
3986
 
  uint used_fields= create_info->used_fields;
 
3993
  uint32_t used_fields= create_info->used_fields;
3987
3994
  KEY *key_info=table->key_info;
3988
3995
  bool rc= true;
3989
3996
 
4008
4015
  }
4009
4016
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
4010
4017
    create_info->key_block_size= table->s->key_block_size;
4011
 
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
4012
 
    create_info->transactional= table->s->transactional;
4013
4018
 
4014
4019
  restore_record(table, s->default_values);     // Empty record for DEFAULT
4015
4020
  Create_field *def;
4054
4059
    if (def)
4055
4060
    {                                           // Field is changed
4056
4061
      def->field=field;
 
4062
      if (field->is_stored != def->is_stored)
 
4063
      {
 
4064
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
4065
                 MYF(0),
 
4066
                 "Changing the STORED status");
 
4067
        goto err;
 
4068
      }
4057
4069
      if (!def->after)
4058
4070
        {
4059
4071
        new_create_list.push_back(def);
4103
4115
      either has a default value or the '0000-00-00' is allowed by the
4104
4116
      set sql mode.
4105
4117
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4106
 
      flag to allow ALTER TABLE only if the table to be altered is empty.
 
4118
      flag to allow ALTER Table only if the table to be altered is empty.
4107
4119
      */
4108
 
    if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
 
4120
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4109
4121
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4110
4122
         !alter_info->datetime_field &&
4111
4123
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4112
 
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
 
4124
         session->variables.sql_mode & MODE_NO_ZERO_DATE)
4113
4125
    {
4114
4126
        alter_info->datetime_field= def;
4115
4127
        alter_info->error_if_not_empty= true;
4135
4147
      find_it.after(def);                       // Put element after this
4136
4148
      /*
4137
4149
        XXX: hack for Bug#28427.
4138
 
        If column order has changed, force OFFLINE ALTER TABLE
 
4150
        If column order has changed, force OFFLINE ALTER Table
4139
4151
        without querying engine capabilities.  If we ever have an
4140
 
        engine that supports online ALTER TABLE CHANGE COLUMN
 
4152
        engine that supports online ALTER Table CHANGE COLUMN
4141
4153
        <name> AFTER <name1> (Falcon?), this fix will effectively
4142
4154
        disable the capability.
4143
4155
        TODO: detect the situation in compare_tables, behave based
4145
4157
      */
4146
4158
      if (alter_info->build_method == HA_BUILD_ONLINE)
4147
4159
      {
4148
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4160
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4149
4161
        goto err;
4150
4162
      }
4151
4163
      alter_info->build_method= HA_BUILD_OFFLINE;
4169
4181
    for which some fields exists.
4170
4182
    */
4171
4183
 
4172
 
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
 
4184
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
4173
4185
    {
4174
4186
    char *key_name= key_info->name;
4175
4187
    Alter_drop *drop;
4188
4200
 
4189
4201
    KEY_PART_INFO *key_part= key_info->key_part;
4190
4202
    key_parts.empty();
4191
 
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
 
4203
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
4192
4204
    {
4193
4205
      if (!key_part->field)
4194
4206
        continue;                               // Wrong field (from UNIREG)
4209
4221
      }
4210
4222
      if (!cfield)
4211
4223
        continue;                               // Field is removed
4212
 
      uint key_part_length=key_part->length;
 
4224
      uint32_t key_part_length=key_part->length;
4213
4225
      if (cfield->field)                        // Not new field
4214
4226
      {
4215
4227
        /*
4252
4264
 
4253
4265
      if (key_info->flags & HA_NOSAME)
4254
4266
      {
4255
 
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
 
4267
        if (is_primary_key_name(key_name))
4256
4268
          key_type= Key::PRIMARY;
4257
4269
        else
4258
4270
          key_type= Key::UNIQUE;
4271
4283
    Key *key;
4272
4284
    while ((key=key_it++))                      // Add new keys
4273
4285
    {
 
4286
      if (key->type == Key::FOREIGN_KEY &&
 
4287
          ((Foreign_key *)key)->validate(new_create_list))
 
4288
        goto err;
4274
4289
      if (key->type != Key::FOREIGN_KEY)
4275
4290
        new_key_list.push_back(key);
4276
 
      if (key->name.str &&
4277
 
          !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
 
4291
      if (key->name.str && is_primary_key_name(key->name.str))
4278
4292
      {
4279
4293
        my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
4280
4294
        goto err;
4331
4345
 
4332
4346
  SYNOPSIS
4333
4347
    mysql_alter_table()
4334
 
      thd              Thread handle
 
4348
      session              Thread handle
4335
4349
      new_db           If there is a RENAME clause
4336
4350
      new_name         If there is a RENAME clause
4337
4351
      create_info      Information from the parsing phase about new
4339
4353
      table_list       The table to change.
4340
4354
      alter_info       Lists of fields, keys to be changed, added
4341
4355
                       or dropped.
4342
 
      order_num        How many ORDER BY fields has been specified.
4343
 
      order            List of fields to ORDER BY.
4344
 
      ignore           Whether we have ALTER IGNORE TABLE
 
4356
      order_num        How many order_st BY fields has been specified.
 
4357
      order            List of fields to order_st BY.
 
4358
      ignore           Whether we have ALTER IGNORE Table
4345
4359
 
4346
4360
  DESCRIPTION
4347
4361
    This is a veery long function and is everything but the kitchen sink :)
4348
 
    It is used to alter a table and not only by ALTER TABLE but also
 
4362
    It is used to alter a table and not only by ALTER Table but also
4349
4363
    CREATE|DROP INDEX are mapped on this function.
4350
4364
 
4351
 
    When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
 
4365
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
4352
4366
    or both, then this function short cuts its operation by renaming
4353
4367
    the table and/or enabling/disabling the keys. In this case, the FRM is
4354
4368
    not changed, directly by mysql_alter_table. However, if there is a
4368
4382
    true   Error
4369
4383
*/
4370
4384
 
4371
 
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 
4385
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4372
4386
                       HA_CREATE_INFO *create_info,
4373
 
                       TABLE_LIST *table_list,
 
4387
                       TableList *table_list,
4374
4388
                       Alter_info *alter_info,
4375
 
                       uint order_num, ORDER *order, bool ignore)
 
4389
                       uint32_t order_num, order_st *order, bool ignore)
4376
4390
{
4377
 
  TABLE *table, *new_table=0, *name_lock= 0;;
 
4391
  Table *table, *new_table=0, *name_lock= 0;;
 
4392
  string new_name_str;
4378
4393
  int error= 0;
4379
4394
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4380
4395
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4381
4396
  char path[FN_REFLEN];
4382
4397
  ha_rows copied= 0,deleted= 0;
4383
4398
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
4384
 
  legacy_db_type table_type;
4385
 
  frm_type_enum frm_type;
 
4399
 
 
4400
  new_name_buff[0]= '\0';
4386
4401
 
4387
4402
  if (table_list && table_list->schema_table)
4388
4403
  {
4389
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
4404
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4390
4405
    return(true);
4391
4406
  }
4392
4407
 
4395
4410
    to simplify further comparisons: we want to see if it's a RENAME
4396
4411
    later just by comparing the pointers, avoiding the need for strcmp.
4397
4412
  */
4398
 
  thd_proc_info(thd, "init");
 
4413
  session->set_proc_info("init");
4399
4414
  table_name=table_list->table_name;
4400
4415
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4401
4416
  db=table_list->db;
4403
4418
    new_db= db;
4404
4419
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
4405
4420
 
4406
 
  mysql_ha_rm_tables(thd, table_list, false);
 
4421
  mysql_ha_rm_tables(session, table_list, false);
4407
4422
 
4408
 
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
 
4423
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4409
4424
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4410
4425
    /* Conditionally writes to binlog. */
4411
 
    return(mysql_discard_or_import_tablespace(thd,table_list,
 
4426
    return(mysql_discard_or_import_tablespace(session,table_list,
4412
4427
                                              alter_info->tablespace_op));
4413
 
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
4414
 
           "/", table_name, reg_ext, NullS);
4415
 
  (void) unpack_filename(new_name_buff, new_name_buff);
 
4428
  ostringstream oss;
 
4429
  oss << drizzle_data_home << "/" << db << "/" << table_name << reg_ext;
 
4430
 
 
4431
  (void) unpack_filename(new_name_buff, oss.str().c_str());
4416
4432
  /*
4417
4433
    If this is just a rename of a view, short cut to the
4418
4434
    following scenario: 1) lock LOCK_open 2) do a RENAME
4419
4435
    2) unlock LOCK_open.
4420
4436
    This is a copy-paste added to make sure
4421
 
    ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
 
4437
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
4422
4438
    as an independent branch in mysql_execute_command. The need
4423
 
    for a copy-paste arose because the main code flow of ALTER TABLE
 
4439
    for a copy-paste arose because the main code flow of ALTER Table
4424
4440
    ... RENAME tries to use open_ltable, which does not work for views
4425
4441
    (open_ltable was never modified to merge table lists of child tables
4426
4442
    into the main table list, like open_tables does).
4427
4443
    This code is wrong and will be removed, please do not copy.
4428
4444
  */
4429
 
  frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
4430
4445
 
4431
 
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
 
4446
  if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4432
4447
    return(true);
4433
4448
  table->use_all_columns();
4434
4449
 
4435
4450
  /* Check that we are not trying to rename to an existing table */
4436
4451
  if (new_name)
4437
4452
  {
4438
 
    stpcpy(new_name_buff,new_name);
4439
 
    stpcpy(new_alias= new_alias_buff, new_name);
 
4453
    strcpy(new_name_buff,new_name);
 
4454
    strcpy(new_alias= new_alias_buff, new_name);
4440
4455
    if (lower_case_table_names)
4441
4456
    {
4442
4457
      if (lower_case_table_names != 2)
4443
4458
      {
4444
 
        my_casedn_str(files_charset_info, new_name_buff);
4445
 
        new_alias= new_name;                    // Create lower case table name
 
4459
        my_casedn_str(files_charset_info, new_name_buff);
 
4460
        new_alias= new_name;                    // Create lower case table name
4446
4461
      }
4447
4462
      my_casedn_str(files_charset_info, new_name);
4448
4463
    }
4459
4474
    {
4460
4475
      if (table->s->tmp_table != NO_TMP_TABLE)
4461
4476
      {
4462
 
        if (find_temporary_table(thd,new_db,new_name_buff))
 
4477
        if (find_temporary_table(session,new_db,new_name_buff))
4463
4478
        {
4464
4479
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
4465
4480
          return(true);
4467
4482
      }
4468
4483
      else
4469
4484
      {
4470
 
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
 
4485
        if (lock_table_name_if_not_cached(session, new_db, new_name, &name_lock))
4471
4486
          return(true);
4472
4487
        if (!name_lock)
4473
4488
        {
4498
4513
    create_info->db_type= old_db_type;
4499
4514
  }
4500
4515
 
4501
 
  if (check_engine(thd, new_name, create_info))
 
4516
  if (check_engine(session, new_name, create_info))
4502
4517
    goto err;
4503
4518
  new_db_type= create_info->db_type;
4504
4519
 
4513
4528
  if (create_info->row_type == ROW_TYPE_NOT_USED)
4514
4529
    create_info->row_type= table->s->row_type;
4515
4530
 
4516
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
4517
 
      ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
 
4531
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_ALTER_NOT_SUPPORTED) ||
 
4532
      ha_check_storage_engine_flag(new_db_type, HTON_BIT_ALTER_NOT_SUPPORTED))
4518
4533
  {
4519
4534
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4520
4535
    goto err;
4521
4536
  }
4522
4537
 
4523
 
  thd_proc_info(thd, "setup");
 
4538
  session->set_proc_info("setup");
4524
4539
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4525
4540
      !table->s->tmp_table) // no need to touch frm
4526
4541
  {
4530
4545
    case ENABLE:
4531
4546
      /*
4532
4547
        wait_while_table_is_used() ensures that table being altered is
4533
 
        opened only by this thread and that TABLE::TABLE_SHARE::version
4534
 
        of TABLE object corresponding to this table is 0.
 
4548
        opened only by this thread and that Table::TABLE_SHARE::version
 
4549
        of Table object corresponding to this table is 0.
4535
4550
        The latter guarantees that no DML statement will open this table
4536
 
        until ALTER TABLE finishes (i.e. until close_thread_tables())
 
4551
        until ALTER Table finishes (i.e. until close_thread_tables())
4537
4552
        while the fact that the table is still open gives us protection
4538
4553
        from concurrent DDL statements.
4539
4554
      */
4540
 
      VOID(pthread_mutex_lock(&LOCK_open));
4541
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4542
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
4555
      pthread_mutex_lock(&LOCK_open);
 
4556
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
4557
      pthread_mutex_unlock(&LOCK_open);
4543
4558
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4544
4559
      /* COND_refresh will be signaled in close_thread_tables() */
4545
4560
      break;
4546
4561
    case DISABLE:
4547
 
      VOID(pthread_mutex_lock(&LOCK_open));
4548
 
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4549
 
      VOID(pthread_mutex_unlock(&LOCK_open));
 
4562
      pthread_mutex_lock(&LOCK_open);
 
4563
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
4564
      pthread_mutex_unlock(&LOCK_open);
4550
4565
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4551
4566
      /* COND_refresh will be signaled in close_thread_tables() */
4552
4567
      break;
4558
4573
    if (error == HA_ERR_WRONG_COMMAND)
4559
4574
    {
4560
4575
      error= 0;
4561
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4576
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4562
4577
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4563
4578
                          table->alias);
4564
4579
    }
4565
4580
 
4566
 
    VOID(pthread_mutex_lock(&LOCK_open));
 
4581
    pthread_mutex_lock(&LOCK_open);
4567
4582
    /*
4568
4583
      Unlike to the above case close_cached_table() below will remove ALL
4569
 
      instances of TABLE from table cache (it will also remove table lock
 
4584
      instances of Table from table cache (it will also remove table lock
4570
4585
      held by this thread). So to make actual table renaming and writing
4571
4586
      to binlog atomic we have to put them into the same critical section
4572
4587
      protected by LOCK_open mutex. This also removes gap for races between
4575
4590
 
4576
4591
    if (!error && (new_name != table_name || new_db != db))
4577
4592
    {
4578
 
      thd_proc_info(thd, "rename");
 
4593
      session->set_proc_info("rename");
4579
4594
      /*
4580
4595
        Then do a 'simple' rename of the table. First we need to close all
4581
4596
        instances of 'source' table.
4582
4597
      */
4583
 
      close_cached_table(thd, table);
 
4598
      close_cached_table(session, table);
4584
4599
      /*
4585
4600
        Then, we want check once again that target table does not exist.
4586
4601
        Actually the order of these two steps does not matter since
4601
4616
          error= -1;
4602
4617
        else if (0)
4603
4618
      {
4604
 
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
4605
 
                                  table_name, 0));
 
4619
          mysql_rename_table(old_db_type, new_db, new_alias, db,
 
4620
                             table_name, 0);
4606
4621
          error= -1;
4607
4622
      }
4608
4623
    }
4611
4626
    if (error == HA_ERR_WRONG_COMMAND)
4612
4627
  {
4613
4628
      error= 0;
4614
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4629
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
4615
4630
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4616
4631
                          table->alias);
4617
4632
  }
4618
4633
 
4619
4634
    if (!error)
4620
4635
    {
4621
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4622
 
      my_ok(thd);
 
4636
      write_bin_log(session, true, session->query, session->query_length);
 
4637
      session->my_ok();
4623
4638
  }
4624
4639
    else if (error > 0)
4625
4640
  {
4627
4642
      error= -1;
4628
4643
    }
4629
4644
    if (name_lock)
4630
 
      unlink_open_table(thd, name_lock, false);
4631
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4645
      unlink_open_table(session, name_lock, false);
 
4646
    pthread_mutex_unlock(&LOCK_open);
4632
4647
    table_list->table= NULL;                    // For query cache
4633
4648
    return(error);
4634
4649
  }
4636
4651
  /* We have to do full alter table. */
4637
4652
 
4638
4653
    /*
4639
 
    If the old table had partitions and we are doing ALTER TABLE ...
 
4654
    If the old table had partitions and we are doing ALTER Table ...
4640
4655
    engine= <new_engine>, the new table must preserve the original
4641
4656
    partitioning. That means that the new engine is still the
4642
4657
    partitioning engine, not the engine specified in the parser.
4648
4663
  */
4649
4664
  new_db_type= create_info->db_type;
4650
4665
 
4651
 
  if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
 
4666
  if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4652
4667
      goto err;
4653
4668
 
4654
 
  set_table_default_charset(thd, create_info, db);
4655
 
 
4656
 
 
4657
 
  if (thd->variables.old_alter_table
 
4669
  set_table_default_charset(session, create_info, db);
 
4670
 
 
4671
  if (session->variables.old_alter_table
4658
4672
      || (table->s->db_type() != create_info->db_type)
4659
4673
     )
4660
4674
  {
4661
4675
    if (alter_info->build_method == HA_BUILD_ONLINE)
4662
4676
    {
4663
 
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
4677
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4664
4678
      goto err;
4665
4679
    }
4666
4680
    alter_info->build_method= HA_BUILD_OFFLINE;
4668
4682
 
4669
4683
  if (alter_info->build_method != HA_BUILD_OFFLINE)
4670
4684
  {
4671
 
    TABLE *altered_table= 0;
 
4685
    Table *altered_table= 0;
4672
4686
    HA_ALTER_INFO ha_alter_info;
4673
4687
    HA_ALTER_FLAGS ha_alter_flags;
4674
 
    uint table_changes= IS_EQUAL_YES;
 
4688
    uint32_t table_changes= IS_EQUAL_YES;
4675
4689
    bool need_copy_table= true;
4676
4690
    /* Check how much the tables differ. */
4677
 
    if (compare_tables(thd, table, alter_info,
 
4691
    if (compare_tables(session, table, alter_info,
4678
4692
                       create_info, order_num,
4679
4693
                       &ha_alter_flags,
4680
4694
                       &ha_alter_info,
4697
4711
    if (new_name == table_name && new_db == db &&
4698
4712
        ha_alter_flags.is_set())
4699
4713
    {
4700
 
      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
 
4714
      Alter_info tmp_alter_info(*alter_info, session->mem_root);
4701
4715
 
4702
4716
      /*
4703
4717
        If no table rename,
4704
4718
        check if table can be altered on-line
4705
4719
      */
4706
 
      if (!(altered_table= create_altered_table(thd,
 
4720
      if (!(altered_table= create_altered_table(session,
4707
4721
                                                table,
4708
4722
                                                new_db,
4709
4723
                                                create_info,
4720
4734
        /*
4721
4735
          @todo: Currently we always acquire an exclusive name
4722
4736
          lock on the table metadata when performing fast or online
4723
 
          ALTER TABLE. In future we may consider this unnecessary,
 
4737
          ALTER Table. In future we may consider this unnecessary,
4724
4738
          and narrow the scope of the exclusive name lock to only
4725
4739
          cover manipulation with .frms. Storage engine API
4726
4740
          call check_if_supported_alter has provision for this
4731
4745
      case HA_ALTER_NOT_SUPPORTED:
4732
4746
        if (alter_info->build_method == HA_BUILD_ONLINE)
4733
4747
        {
4734
 
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4735
 
          close_temporary_table(thd, altered_table, 1, 1);
 
4748
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
 
4749
          close_temporary_table(session, altered_table, 1, 1);
4736
4750
          goto err;
4737
4751
        }
4738
4752
        need_copy_table= true;
4739
4753
        break;
4740
4754
      case HA_ALTER_ERROR:
4741
4755
      default:
4742
 
        close_temporary_table(thd, altered_table, 1, 1);
 
4756
        close_temporary_table(session, altered_table, 1, 1);
4743
4757
        goto err;
4744
4758
      }
4745
4759
 
4746
4760
    }
4747
 
    /* TODO need to check if changes can be handled as fast ALTER TABLE */
 
4761
    /* TODO need to check if changes can be handled as fast ALTER Table */
4748
4762
    if (!altered_table)
4749
4763
      need_copy_table= true;
4750
4764
 
4751
4765
    if (!need_copy_table)
4752
4766
    {
4753
 
      error= mysql_fast_or_online_alter_table(thd,
 
4767
      error= mysql_fast_or_online_alter_table(session,
4754
4768
                                              table,
4755
4769
                                              altered_table,
4756
4770
                                              create_info,
4757
4771
                                              &ha_alter_info,
4758
4772
                                              &ha_alter_flags,
4759
4773
                                              alter_info->keys_onoff);
4760
 
      if (thd->lock)
 
4774
      if (session->lock)
4761
4775
      {
4762
 
        mysql_unlock_tables(thd, thd->lock);
4763
 
        thd->lock=0;
 
4776
        mysql_unlock_tables(session, session->lock);
 
4777
        session->lock=0;
4764
4778
      }
4765
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4779
      close_temporary_table(session, altered_table, 1, 1);
4766
4780
 
4767
4781
      if (error)
4768
4782
      {
4781
4795
    }
4782
4796
 
4783
4797
    if (altered_table)
4784
 
      close_temporary_table(thd, altered_table, 1, 1);
 
4798
      close_temporary_table(session, altered_table, 1, 1);
4785
4799
  }
4786
4800
 
4787
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4788
 
           current_pid, thd->thread_id);
 
4801
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
 
4802
           (unsigned long)current_pid, session->thread_id);
4789
4803
  /* Safety fix for innodb */
4790
4804
  if (lower_case_table_names)
4791
4805
    my_casedn_str(files_charset_info, tmp_name);
4792
4806
 
4793
4807
 
4794
4808
  /* Create a temporary table with the new format */
4795
 
  if ((error= create_temporary_table(thd, table, new_db, tmp_name, 
4796
 
                                     create_info, alter_info, 
 
4809
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
 
4810
                                     create_info, alter_info,
4797
4811
                                     !strcmp(db, new_db))))
4798
4812
  {
4799
4813
    goto err;
4802
4816
  /* Open the table so we need to copy the data to it. */
4803
4817
  if (table->s->tmp_table)
4804
4818
  {
4805
 
    TABLE_LIST tbl;
 
4819
    TableList tbl;
4806
4820
    memset(&tbl, 0, sizeof(tbl));
4807
4821
    tbl.db= new_db;
4808
4822
    tbl.table_name= tbl.alias= tmp_name;
4809
 
    /* Table is in thd->temporary_tables */
4810
 
    new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
4811
 
                          DRIZZLE_LOCK_IGNORE_FLUSH);
 
4823
    /* Table is in session->temporary_tables */
 
4824
    new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4812
4825
  }
4813
4826
  else
4814
4827
  {
4815
 
    char path[FN_REFLEN];
 
4828
    char tmp_path[FN_REFLEN];
4816
4829
    /* table is a normal table: Create temporary table in same directory */
4817
 
    build_table_filename(path, sizeof(path), new_db, tmp_name, "",
 
4830
    build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, "",
4818
4831
                         FN_IS_TMP);
4819
4832
    /* Open our intermediate table */
4820
 
    new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
 
4833
    new_table=open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
4821
4834
  }
4822
4835
  if (!new_table)
4823
4836
    goto err1;
4824
4837
 
4825
4838
  /* Copy the data if necessary. */
4826
 
  thd->count_cuted_fields= CHECK_FIELD_WARN;    // calc cuted fields
4827
 
  thd->cuted_fields=0L;
4828
 
  thd_proc_info(thd, "copy to tmp table");
 
4839
  session->count_cuted_fields= CHECK_FIELD_WARN;        // calc cuted fields
 
4840
  session->cuted_fields=0L;
 
4841
  session->set_proc_info("copy to tmp table");
4829
4842
  copied=deleted=0;
4830
4843
  /*
4831
4844
    We do not copy data for MERGE tables. Only the children have data.
4833
4846
  */
4834
4847
  if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
4835
4848
  {
4836
 
    /* We don't want update TIMESTAMP fields during ALTER TABLE. */
 
4849
    /* We don't want update TIMESTAMP fields during ALTER Table. */
4837
4850
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
4838
4851
    new_table->next_number_field=new_table->found_next_number_field;
4839
4852
    error= copy_data_between_tables(table, new_table,
4844
4857
  }
4845
4858
  else
4846
4859
  {
4847
 
    VOID(pthread_mutex_lock(&LOCK_open));
4848
 
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4849
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4860
    pthread_mutex_lock(&LOCK_open);
 
4861
    wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
4862
    pthread_mutex_unlock(&LOCK_open);
4850
4863
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4851
4864
                            alter_info->keys_onoff);
4852
 
    error= ha_autocommit_or_rollback(thd, 0);
4853
 
    if (end_active_trans(thd))
 
4865
    error= ha_autocommit_or_rollback(session, 0);
 
4866
    if (end_active_trans(session))
4854
4867
      error= 1;
4855
4868
  }
4856
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
 
4869
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
4857
4870
 
4858
4871
  if (table->s->tmp_table != NO_TMP_TABLE)
4859
4872
  {
4861
4874
    if (error)
4862
4875
      goto err1;
4863
4876
    /* Close lock if this is a transactional table */
4864
 
    if (thd->lock)
 
4877
    if (session->lock)
4865
4878
    {
4866
 
      mysql_unlock_tables(thd, thd->lock);
4867
 
      thd->lock=0;
 
4879
      mysql_unlock_tables(session, session->lock);
 
4880
      session->lock=0;
4868
4881
    }
4869
4882
    /* Remove link to old table and rename the new one */
4870
 
    close_temporary_table(thd, table, 1, 1);
 
4883
    close_temporary_table(session, table, 1, 1);
4871
4884
    /* Should pass the 'new_name' as we store table name in the cache */
4872
 
    if (rename_temporary_table(thd, new_table, new_db, new_name))
 
4885
    if (rename_temporary_table(session, new_table, new_db, new_name))
4873
4886
      goto err1;
4874
 
    /* We don't replicate alter table statement on temporary tables */
4875
 
    if (!thd->current_stmt_binlog_row_based)
4876
 
      write_bin_log(thd, true, thd->query, thd->query_length);
4877
4887
    goto end_temporary;
4878
4888
  }
4879
4889
 
4884
4894
      Note that MERGE tables do not have their children attached here.
4885
4895
    */
4886
4896
    intern_close_table(new_table);
4887
 
    my_free(new_table,MYF(0));
 
4897
    free(new_table);
4888
4898
  }
4889
 
  VOID(pthread_mutex_lock(&LOCK_open));
 
4899
  pthread_mutex_lock(&LOCK_open);
4890
4900
  if (error)
4891
4901
  {
4892
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4893
 
    VOID(pthread_mutex_unlock(&LOCK_open));
 
4902
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
4903
    pthread_mutex_unlock(&LOCK_open);
4894
4904
    goto err;
4895
4905
  }
4896
4906
 
4901
4911
       with exclusive name-locks.
4902
4912
    3) Rename the old table to a temp name, rename the new one to the
4903
4913
       old name.
4904
 
    4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
 
4914
    4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
4905
4915
       we reopen new version of table.
4906
4916
    5) Write statement to the binary log.
4907
 
    6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
 
4917
    6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
4908
4918
       remove name-locks from list of open tables and table cache.
4909
4919
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
4910
4920
       call to remove name-locks from table cache and list of open table.
4911
4921
  */
4912
4922
 
4913
 
  thd_proc_info(thd, "rename result table");
4914
 
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
4915
 
           current_pid, thd->thread_id);
 
4923
  session->set_proc_info("rename result table");
 
4924
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
 
4925
           (unsigned long)current_pid, session->thread_id);
4916
4926
  if (lower_case_table_names)
4917
4927
    my_casedn_str(files_charset_info, old_name);
4918
4928
 
4919
 
  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4920
 
  close_data_files_and_morph_locks(thd, db, table_name);
 
4929
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
 
4930
  close_data_files_and_morph_locks(session, db, table_name);
4921
4931
 
4922
4932
  error=0;
4923
4933
  save_old_db_type= old_db_type;
4927
4937
    mysql_rename_table(), because we just juggle with the FRM and nothing
4928
4938
    more. If we have an intermediate table, then we notify the SE that
4929
4939
    it should become the actual table. Later, we will recycle the old table.
4930
 
    However, in case of ALTER TABLE RENAME there might be no intermediate
 
4940
    However, in case of ALTER Table RENAME there might be no intermediate
4931
4941
    table. This is when the old and new tables are compatible, according to
4932
4942
    compare_table(). Then, we need one additional call to
4933
4943
    mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
4939
4949
                         FN_TO_IS_TMP))
4940
4950
  {
4941
4951
    error=1;
4942
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
4952
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4943
4953
  }
4944
4954
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
4945
4955
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
4946
4956
  {
4947
4957
    /* Try to get everything back. */
4948
4958
    error=1;
4949
 
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
4950
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4951
 
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
4952
 
                            FN_FROM_IS_TMP));
 
4959
    quick_rm_table(new_db_type,new_db,new_alias, 0);
 
4960
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
4961
    mysql_rename_table(old_db_type, db, old_name, db, alias,
 
4962
                       FN_FROM_IS_TMP);
4953
4963
  }
4954
4964
 
4955
4965
  if (error)
4958
4968
    goto err_with_placeholders;
4959
4969
  }
4960
4970
 
4961
 
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
 
4971
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4962
4972
 
4963
4973
end_online:
4964
 
  if (thd->locked_tables && new_name == table_name && new_db == db)
 
4974
  if (session->locked_tables && new_name == table_name && new_db == db)
4965
4975
  {
4966
 
    thd->in_lock_tables= 1;
4967
 
    error= reopen_tables(thd, 1, 1);
4968
 
    thd->in_lock_tables= 0;
 
4976
    session->in_lock_tables= 1;
 
4977
    error= reopen_tables(session, 1, 1);
 
4978
    session->in_lock_tables= 0;
4969
4979
    if (error)
4970
4980
      goto err_with_placeholders;
4971
4981
  }
4972
 
  VOID(pthread_mutex_unlock(&LOCK_open));
4973
 
 
4974
 
  thd_proc_info(thd, "end");
4975
 
 
4976
 
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
4977
 
                      thd->query, thd->query_length,
4978
 
                      db, table_name);
4979
 
 
4980
 
  assert(!(mysql_bin_log.is_open() &&
4981
 
                thd->current_stmt_binlog_row_based &&
4982
 
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4983
 
  write_bin_log(thd, true, thd->query, thd->query_length);
4984
 
 
4985
 
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
 
4982
  pthread_mutex_unlock(&LOCK_open);
 
4983
 
 
4984
  session->set_proc_info("end");
 
4985
 
 
4986
  write_bin_log(session, true, session->query, session->query_length);
 
4987
 
 
4988
  if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
4986
4989
  {
4987
4990
    /*
4988
4991
      For the alter table to be properly flushed to the logs, we
4989
4992
      have to open the new table.  If not, we get a problem on server
4990
4993
      shutdown. But we do not need to attach MERGE children.
4991
4994
    */
4992
 
    char path[FN_REFLEN];
4993
 
    TABLE *t_table;
4994
 
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
4995
 
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
 
4995
    char table_path[FN_REFLEN];
 
4996
    Table *t_table;
 
4997
    build_table_filename(table_path, sizeof(table_path), new_db, table_name, "", 0);
 
4998
    t_table= open_temporary_table(session, table_path, new_db, tmp_name, false, OTM_OPEN);
4996
4999
    if (t_table)
4997
5000
    {
4998
5001
      intern_close_table(t_table);
4999
 
      my_free(t_table, MYF(0));
 
5002
      free(t_table);
5000
5003
    }
5001
5004
    else
5002
 
      sql_print_warning("Could not open table %s.%s after rename\n",
5003
 
                        new_db,table_name);
 
5005
      errmsg_printf(ERRMSG_LVL_WARN,
 
5006
                    _("Could not open table %s.%s after rename\n"),
 
5007
                    new_db,table_name);
5004
5008
    ha_flush_logs(old_db_type);
5005
5009
  }
5006
5010
  table_list->table=0;                          // For query cache
5007
5011
 
5008
 
  if (thd->locked_tables && (new_name != table_name || new_db != db))
 
5012
  if (session->locked_tables && (new_name != table_name || new_db != db))
5009
5013
  {
5010
5014
    /*
5011
 
      If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
 
5015
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
5012
5016
      to remove placeholders for the old table and for the target table
5013
5017
      from the list of open tables and table cache. If we are not under
5014
5018
      LOCK TABLES we can rely on close_thread_tables() doing this job.
5015
5019
    */
5016
5020
    pthread_mutex_lock(&LOCK_open);
5017
 
    unlink_open_table(thd, table, false);
5018
 
    unlink_open_table(thd, name_lock, false);
 
5021
    unlink_open_table(session, table, false);
 
5022
    unlink_open_table(session, name_lock, false);
5019
5023
    pthread_mutex_unlock(&LOCK_open);
5020
5024
  }
5021
5025
 
5022
5026
end_temporary:
5023
5027
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5024
5028
           (ulong) (copied + deleted), (ulong) deleted,
5025
 
           (ulong) thd->cuted_fields);
5026
 
  my_ok(thd, copied + deleted, 0L, tmp_name);
5027
 
  thd->some_tables_deleted=0;
 
5029
           (ulong) session->cuted_fields);
 
5030
  session->my_ok(copied + deleted, 0L, tmp_name);
 
5031
  session->some_tables_deleted=0;
5028
5032
  return(false);
5029
5033
 
5030
5034
err1:
5031
5035
  if (new_table)
5032
5036
  {
5033
5037
    /* close_temporary_table() frees the new_table pointer. */
5034
 
    close_temporary_table(thd, new_table, 1, 1);
 
5038
    close_temporary_table(session, new_table, 1, 1);
5035
5039
  }
5036
5040
  else
5037
 
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5041
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5038
5042
 
5039
5043
err:
5040
5044
  /*
5043
5047
    the table to be altered isn't empty.
5044
5048
    Report error here.
5045
5049
  */
5046
 
  if (alter_info->error_if_not_empty && thd->row_count)
 
5050
  if (alter_info->error_if_not_empty && session->row_count)
5047
5051
  {
5048
5052
    const char *f_val= 0;
5049
5053
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
5050
5054
    switch (alter_info->datetime_field->sql_type)
5051
5055
    {
5052
 
      case DRIZZLE_TYPE_NEWDATE:
 
5056
      case DRIZZLE_TYPE_DATE:
5053
5057
        f_val= "0000-00-00";
5054
5058
        t_type= DRIZZLE_TIMESTAMP_DATE;
5055
5059
        break;
5061
5065
        /* Shouldn't get here. */
5062
5066
        assert(0);
5063
5067
    }
5064
 
    bool save_abort_on_warning= thd->abort_on_warning;
5065
 
    thd->abort_on_warning= true;
5066
 
    make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
5068
    bool save_abort_on_warning= session->abort_on_warning;
 
5069
    session->abort_on_warning= true;
 
5070
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5067
5071
                                 f_val, strlength(f_val), t_type,
5068
5072
                                 alter_info->datetime_field->field_name);
5069
 
    thd->abort_on_warning= save_abort_on_warning;
 
5073
    session->abort_on_warning= save_abort_on_warning;
5070
5074
  }
5071
5075
  if (name_lock)
5072
5076
  {
5073
5077
    pthread_mutex_lock(&LOCK_open);
5074
 
    unlink_open_table(thd, name_lock, false);
 
5078
    unlink_open_table(session, name_lock, false);
5075
5079
    pthread_mutex_unlock(&LOCK_open);
5076
5080
  }
5077
5081
  return(true);
5082
5086
    being altered. To be safe under LOCK TABLES we should remove placeholders
5083
5087
    from list of open tables list and table cache.
5084
5088
  */
5085
 
  unlink_open_table(thd, table, false);
 
5089
  unlink_open_table(session, table, false);
5086
5090
  if (name_lock)
5087
 
    unlink_open_table(thd, name_lock, false);
5088
 
  VOID(pthread_mutex_unlock(&LOCK_open));
 
5091
    unlink_open_table(session, name_lock, false);
 
5092
  pthread_mutex_unlock(&LOCK_open);
5089
5093
  return(true);
5090
5094
}
5091
5095
/* mysql_alter_table */
5092
5096
 
5093
5097
static int
5094
 
copy_data_between_tables(TABLE *from,TABLE *to,
 
5098
copy_data_between_tables(Table *from,Table *to,
5095
5099
                         List<Create_field> &create,
5096
5100
                         bool ignore,
5097
 
                         uint order_num, ORDER *order,
 
5101
                         uint32_t order_num, order_st *order,
5098
5102
                         ha_rows *copied,
5099
5103
                         ha_rows *deleted,
5100
5104
                         enum enum_enable_or_disable keys_onoff,
5103
5107
  int error;
5104
5108
  Copy_field *copy,*copy_end;
5105
5109
  ulong found_count,delete_count;
5106
 
  THD *thd= current_thd;
5107
 
  uint length= 0;
 
5110
  Session *session= current_session;
 
5111
  uint32_t length= 0;
5108
5112
  SORT_FIELD *sortorder;
5109
5113
  READ_RECORD info;
5110
 
  TABLE_LIST   tables;
 
5114
  TableList   tables;
5111
5115
  List<Item>   fields;
5112
5116
  List<Item>   all_fields;
5113
5117
  ha_rows examined_rows;
5118
5122
  /*
5119
5123
    Turn off recovery logging since rollback of an alter table is to
5120
5124
    delete the new table so there is no need to log the changes to it.
5121
 
    
 
5125
 
5122
5126
    This needs to be done before external_lock
5123
5127
  */
5124
 
  error= ha_enable_transaction(thd, false);
 
5128
  error= ha_enable_transaction(session, false);
5125
5129
  if (error)
5126
5130
    return(-1);
5127
 
  
 
5131
 
5128
5132
  if (!(copy= new Copy_field[to->s->fields]))
5129
5133
    return(-1);                         /* purecov: inspected */
5130
5134
 
5131
 
  if (to->file->ha_external_lock(thd, F_WRLCK))
 
5135
  if (to->file->ha_external_lock(session, F_WRLCK))
5132
5136
    return(-1);
5133
5137
 
5134
5138
  /* We need external lock before we can disable/enable keys */
5135
5139
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5136
5140
 
5137
5141
  /* We can abort alter table for any table type */
5138
 
  thd->abort_on_warning= !ignore;
 
5142
  session->abort_on_warning= !ignore;
5139
5143
 
5140
5144
  from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5141
5145
  to->file->ha_start_bulk_insert(from->file->stats.records);
5142
5146
 
5143
 
  save_sql_mode= thd->variables.sql_mode;
 
5147
  save_sql_mode= session->variables.sql_mode;
5144
5148
 
5145
5149
  List_iterator<Create_field> it(create);
5146
5150
  Create_field *def;
5151
5155
    if (def->field)
5152
5156
    {
5153
5157
      if (*ptr == to->next_number_field)
5154
 
      {
5155
5158
        auto_increment_field_copied= true;
5156
 
        /*
5157
 
          If we are going to copy contents of one auto_increment column to
5158
 
          another auto_increment column it is sensible to preserve zeroes.
5159
 
          This condition also covers case when we are don't actually alter
5160
 
          auto_increment column.
5161
 
        */
5162
 
        if (def->field == from->found_next_number_field)
5163
 
          thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
5164
 
      }
 
5159
 
5165
5160
      (copy_end++)->set(*ptr,def->field,0);
5166
5161
    }
5167
5162
 
5174
5169
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5175
5170
    {
5176
5171
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
5177
 
      snprintf(warn_buff, sizeof(warn_buff), 
5178
 
               "ORDER BY ignored as there is a user-defined clustered index"
5179
 
               " in the table '%-.192s'", from->s->table_name.str);
5180
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
5172
      snprintf(warn_buff, sizeof(warn_buff),
 
5173
               _("order_st BY ignored because there is a user-defined clustered "
 
5174
                 "index in the table '%-.192s'"),
 
5175
               from->s->table_name.str);
 
5176
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5181
5177
                   warn_buff);
5182
5178
    }
5183
5179
    else
5184
5180
    {
5185
 
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5186
 
                                                MYF(MY_FAE | MY_ZEROFILL));
 
5181
      from->sort.io_cache= new IO_CACHE;
 
5182
      memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
 
5183
 
5187
5184
      memset(&tables, 0, sizeof(tables));
5188
5185
      tables.table= from;
5189
5186
      tables.alias= tables.table_name= from->s->table_name.str;
5190
5187
      tables.db= from->s->db.str;
5191
5188
      error= 1;
5192
5189
 
5193
 
      if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5194
 
          setup_order(thd, thd->lex->select_lex.ref_pointer_array,
 
5190
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
 
5191
          setup_order(session, session->lex->select_lex.ref_pointer_array,
5195
5192
                      &tables, fields, all_fields, order) ||
5196
5193
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5197
 
          (from->sort.found_records= filesort(thd, from, sortorder, length,
 
5194
          (from->sort.found_records= filesort(session, from, sortorder, length,
5198
5195
                                              (SQL_SELECT *) 0, HA_POS_ERROR,
5199
5196
                                              1, &examined_rows)) ==
5200
5197
          HA_POS_ERROR)
5204
5201
 
5205
5202
  /* Tell handler that we have values for all columns in the to table */
5206
5203
  to->use_all_columns();
5207
 
  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
 
5204
  init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
5208
5205
  if (ignore)
5209
5206
    to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5210
 
  thd->row_count= 0;
 
5207
  session->row_count= 0;
5211
5208
  restore_record(to, s->default_values);        // Create empty record
5212
5209
  while (!(error=info.read_record(&info)))
5213
5210
  {
5214
 
    if (thd->killed)
 
5211
    if (session->killed)
5215
5212
    {
5216
 
      thd->send_kill_message();
 
5213
      session->send_kill_message();
5217
5214
      error= 1;
5218
5215
      break;
5219
5216
    }
5220
 
    thd->row_count++;
 
5217
    session->row_count++;
5221
5218
    /* Return error if source table isn't empty. */
5222
5219
    if (error_if_not_empty)
5223
5220
    {
5231
5228
      else
5232
5229
        to->next_number_field->reset();
5233
5230
    }
5234
 
    
 
5231
 
5235
5232
    for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
5236
5233
    {
5237
5234
      copy_ptr->do_copy(copy_ptr);
5238
5235
    }
5239
5236
    prev_insert_id= to->file->next_insert_id;
 
5237
    update_virtual_fields_marked_for_write(to, false);
5240
5238
    error=to->file->ha_write_row(to->record[0]);
5241
5239
    to->auto_increment_field_not_null= false;
5242
5240
    if (error)
5246
5244
      {
5247
5245
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
5248
5246
         {
5249
 
           uint key_nr= to->file->get_dup_key(error);
 
5247
           uint32_t key_nr= to->file->get_dup_key(error);
5250
5248
           if ((int) key_nr >= 0)
5251
5249
           {
5252
5250
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
5279
5277
  }
5280
5278
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
5281
5279
 
5282
 
  if (ha_enable_transaction(thd, true))
 
5280
  if (ha_enable_transaction(session, true))
5283
5281
  {
5284
5282
    error= 1;
5285
5283
    goto err;
5289
5287
    Ensure that the new table is saved properly to disk so that we
5290
5288
    can do a rename
5291
5289
  */
5292
 
  if (ha_autocommit_or_rollback(thd, 0))
 
5290
  if (ha_autocommit_or_rollback(session, 0))
5293
5291
    error=1;
5294
 
  if (end_active_trans(thd))
 
5292
  if (end_active_trans(session))
5295
5293
    error=1;
5296
5294
 
5297
5295
 err:
5298
 
  thd->variables.sql_mode= save_sql_mode;
5299
 
  thd->abort_on_warning= 0;
 
5296
  session->variables.sql_mode= save_sql_mode;
 
5297
  session->abort_on_warning= 0;
5300
5298
  free_io_cache(from);
5301
5299
  *copied= found_count;
5302
5300
  *deleted=delete_count;
5303
5301
  to->file->ha_release_auto_increment();
5304
 
  if (to->file->ha_external_lock(thd,F_UNLCK))
 
5302
  if (to->file->ha_external_lock(session,F_UNLCK))
5305
5303
    error=1;
5306
5304
  return(error > 0 ? -1 : 0);
5307
5305
}
5312
5310
 
5313
5311
  SYNOPSIS
5314
5312
    mysql_recreate_table()
5315
 
    thd                 Thread handler
 
5313
    session                     Thread handler
5316
5314
    tables              Tables to recreate
5317
5315
 
5318
5316
 RETURN
5319
5317
    Like mysql_alter_table().
5320
5318
*/
5321
 
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
 
5319
bool mysql_recreate_table(Session *session, TableList *table_list)
5322
5320
{
5323
5321
  HA_CREATE_INFO create_info;
5324
5322
  Alter_info alter_info;
5335
5333
  create_info.default_table_charset=default_charset_info;
5336
5334
  /* Force alter table to recreate table */
5337
5335
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5338
 
  return(mysql_alter_table(thd, NullS, NullS, &create_info,
 
5336
  return(mysql_alter_table(session, NULL, NULL, &create_info,
5339
5337
                                table_list, &alter_info, 0,
5340
 
                                (ORDER *) 0, 0));
 
5338
                                (order_st *) 0, 0));
5341
5339
}
5342
5340
 
5343
5341
 
5344
 
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
 
5342
bool mysql_checksum_table(Session *session, TableList *tables,
5345
5343
                          HA_CHECK_OPT *check_opt)
5346
5344
{
5347
 
  TABLE_LIST *table;
 
5345
  TableList *table;
5348
5346
  List<Item> field_list;
5349
5347
  Item *item;
5350
 
  Protocol *protocol= thd->protocol;
 
5348
  Protocol *protocol= session->protocol;
5351
5349
 
5352
5350
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5353
5351
  item->maybe_null= 1;
5362
5360
  for (table= tables; table; table= table->next_local)
5363
5361
  {
5364
5362
    char table_name[NAME_LEN*2+2];
5365
 
    TABLE *t;
5366
 
 
5367
 
    strxmov(table_name, table->db ,".", table->table_name, NullS);
5368
 
 
5369
 
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5370
 
    thd->clear_error();                 // these errors shouldn't get client
 
5363
    Table *t;
 
5364
 
 
5365
    sprintf(table_name,"%s.%s",table->db,table->table_name);
 
5366
 
 
5367
    t= table->table= open_n_lock_single_table(session, table, TL_READ);
 
5368
    session->clear_error();                     // these errors shouldn't get client
5371
5369
 
5372
5370
    protocol->prepare_for_resend();
5373
5371
    protocol->store(table_name, system_charset_info);
5376
5374
    {
5377
5375
      /* Table didn't exist */
5378
5376
      protocol->store_null();
5379
 
      thd->clear_error();
 
5377
      session->clear_error();
5380
5378
    }
5381
5379
    else
5382
5380
    {
5390
5388
      {
5391
5389
        /* calculating table's checksum */
5392
5390
        ha_checksum crc= 0;
5393
 
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
 
5391
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
5394
5392
 
5395
5393
        t->use_all_columns();
5396
5394
 
5418
5416
              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
5419
5417
            }
5420
5418
 
5421
 
            for (uint i= 0; i < t->s->fields; i++ )
 
5419
            for (uint32_t i= 0; i < t->s->fields; i++ )
5422
5420
            {
5423
5421
              Field *f= t->field[i];
5424
5422
              if ((f->type() == DRIZZLE_TYPE_BLOB) ||
5426
5424
              {
5427
5425
                String tmp;
5428
5426
                f->val_str(&tmp);
5429
 
                row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
 
5427
                row_crc= my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
5430
5428
              }
5431
5429
              else
5432
5430
                row_crc= my_checksum(row_crc, f->ptr,
5439
5437
          t->file->ha_rnd_end();
5440
5438
        }
5441
5439
      }
5442
 
      thd->clear_error();
5443
 
      close_thread_tables(thd);
 
5440
      session->clear_error();
 
5441
      close_thread_tables(session);
5444
5442
      table->table=0;                           // For query cache
5445
5443
    }
5446
5444
    if (protocol->write())
5447
5445
      goto err;
5448
5446
  }
5449
5447
 
5450
 
  my_eof(thd);
 
5448
  session->my_eof();
5451
5449
  return(false);
5452
5450
 
5453
5451
 err:
5454
 
  close_thread_tables(thd);                     // Shouldn't be needed
 
5452
  close_thread_tables(session);                 // Shouldn't be needed
5455
5453
  if (table)
5456
5454
    table->table=0;
5457
5455
  return(true);
5458
5456
}
5459
5457
 
5460
 
static bool check_engine(THD *thd, const char *table_name,
 
5458
static bool check_engine(Session *session, const char *table_name,
5461
5459
                         HA_CREATE_INFO *create_info)
5462
5460
{
5463
5461
  handlerton **new_engine= &create_info->db_type;
5464
5462
  handlerton *req_engine= *new_engine;
5465
5463
  bool no_substitution= 1;
5466
 
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
 
5464
  if (!(*new_engine= ha_checktype(session, ha_legacy_type(req_engine),
5467
5465
                                  no_substitution, 1)))
5468
5466
    return true;
5469
5467
 
5470
5468
  if (req_engine && req_engine != *new_engine)
5471
5469
  {
5472
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5470
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5473
5471
                       ER_WARN_USING_OTHER_HANDLER,
5474
5472
                       ER(ER_WARN_USING_OTHER_HANDLER),
5475
5473
                       ha_resolve_storage_engine_name(*new_engine),
5476
5474
                       table_name);
5477
5475
  }
5478
5476
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5479
 
      ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
 
5477
      ha_check_storage_engine_flag(*new_engine, HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5480
5478
  {
5481
5479
    if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5482
5480
    {