~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_table.cc

  • Committer: Stewart Smith
  • Date: 2008-07-13 08:00:16 UTC
  • mto: (210.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: stewart@flamingspork.com-20080713080016-8qtjv9ypt42azzr6
CRC32() as UDF

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* drop and alter of tables */
17
17
 
18
 
#include <drizzled/server_includes.h>
19
 
#include <storage/myisam/myisam.h>
20
 
#include <drizzled/show.h>
21
 
#include <drizzled/error.h>
22
 
#include <drizzled/gettext.h>
23
 
#include <drizzled/data_home.h>
24
 
#include <drizzled/sql_parse.h>
25
 
#include <mysys/hash.h>
26
 
#include <drizzled/sql_lex.h>
27
 
#include <drizzled/session.h>
28
 
#include <drizzled/sql_base.h>
29
 
#include <drizzled/db.h>
30
 
#include <drizzled/lock.h>
31
 
#include <drizzled/unireg.h>
32
 
#include <drizzled/item/int.h>
33
 
#include <drizzled/item/empty_string.h>
34
 
#include <drizzled/transaction_services.h>
35
 
 
36
 
 
37
 
using namespace std;
38
 
extern drizzled::TransactionServices transaction_services;
39
 
extern HASH lock_db_cache;
 
18
#include "mysql_priv.h"
 
19
#include <hash.h>
 
20
#include <myisam.h>
 
21
#include <my_dir.h>
 
22
#include "sql_show.h"
40
23
 
41
24
int creating_table= 0;        // How many mysql_create_table are running
42
25
 
43
 
 
44
 
bool is_primary_key(KEY *key_info)
45
 
{
46
 
  static const char * primary_key_name="PRIMARY";
47
 
  return (strcmp(key_info->name, primary_key_name)==0);
48
 
}
49
 
 
50
 
const char* is_primary_key_name(const char* key_name)
51
 
{
52
 
  static const char * primary_key_name="PRIMARY";
53
 
  if (strcmp(key_name, primary_key_name)==0)
54
 
    return key_name;
55
 
  else
56
 
    return NULL;
57
 
}
 
26
const char *primary_key_name="PRIMARY";
58
27
 
59
28
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
60
29
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
61
 
static int copy_data_between_tables(Table *from,Table *to,
 
30
static int copy_data_between_tables(TABLE *from,TABLE *to,
62
31
                                    List<Create_field> &create, bool ignore,
63
 
                                    uint32_t order_num, order_st *order,
 
32
                                    uint order_num, ORDER *order,
64
33
                                    ha_rows *copied,ha_rows *deleted,
65
34
                                    enum enum_enable_or_disable keys_onoff,
66
35
                                    bool error_if_not_empty);
67
36
 
68
 
static bool prepare_blob_field(Session *session, Create_field *sql_field);
69
 
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
 
37
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
 
38
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
70
39
static int
71
 
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
 
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
72
41
                           Alter_info *alter_info,
73
42
                           bool tmp_table,
74
 
                               uint32_t *db_options,
 
43
                               uint *db_options,
75
44
                               handler *file, KEY **key_info_buffer,
76
 
                               uint32_t *key_count, int select_field_count);
 
45
                               uint *key_count, int select_field_count);
77
46
static bool
78
 
mysql_prepare_alter_table(Session *session, Table *table,
 
47
mysql_prepare_alter_table(THD *thd, TABLE *table,
79
48
                          HA_CREATE_INFO *create_info,
80
49
                          Alter_info *alter_info);
81
50
 
82
 
static void set_table_default_charset(Session *session,
83
 
                                      HA_CREATE_INFO *create_info, char *db)
84
 
{
85
 
  /*
86
 
    If the table character set was not given explicitly,
87
 
    let's fetch the database default character set and
88
 
    apply it to the table.
89
 
  */
90
 
  if (!create_info->default_table_charset)
91
 
  {
92
 
    HA_CREATE_INFO db_info;
93
 
 
94
 
    load_db_opt_by_name(session, db, &db_info);
95
 
 
96
 
    create_info->default_table_charset= db_info.default_table_charset;
97
 
  }
98
 
}
99
 
 
100
51
/*
101
52
  Translate a file name to a table name (WL #1324).
102
53
 
109
60
  RETURN
110
61
    Table name length.
111
62
*/
112
 
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
 
63
uint filename_to_tablename(const char *from, char *to, uint to_length)
113
64
{
114
 
  uint32_t errors;
115
 
  uint32_t res;
 
65
  uint errors;
 
66
  uint res;
116
67
 
117
 
  if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
 
68
  if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
118
69
  {
119
70
    /* Temporary table name. */
120
 
    res= strlen(strncpy(to, from, to_length));
 
71
    res= (strnmov(to, from, to_length) - to);
121
72
  }
122
73
  else
123
74
  {
125
76
                    system_charset_info,  to, to_length, &errors);
126
77
    if (errors) // Old 5.0 name
127
78
    {
128
 
      to[0]='\0';
129
 
      strncat(to, from, to_length-1);
130
 
      res= strlen(to);
131
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid (old?) table or database name '%s'"), from);
 
79
      res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX,  from, NullS) -
 
80
            to);
 
81
      sql_print_error("Invalid (old?) table or database name '%s'", from);
 
82
      /*
 
83
        TODO: add a stored procedure for fix table and database names,
 
84
        and mention its name in error log.
 
85
      */
132
86
    }
133
87
  }
134
88
 
148
102
  RETURN
149
103
    File name length.
150
104
*/
151
 
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
 
105
 
 
106
uint tablename_to_filename(const char *from, char *to, uint to_length)
152
107
{
153
 
  uint32_t errors, length;
 
108
  uint errors, length;
154
109
 
 
110
  if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
 
111
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
 
112
    return((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
 
113
                                to_length-1) -
 
114
                        (from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
155
115
  length= strconvert(system_charset_info, from,
156
116
                     &my_charset_filename, to, to_length, &errors);
157
117
  if (check_if_legal_tablename(to) &&
165
125
 
166
126
 
167
127
/*
168
 
  Creates path to a file: drizzle_data_dir/db/table.ext
 
128
  Creates path to a file: mysql_data_dir/db/table.ext
169
129
 
170
130
  SYNOPSIS
171
131
   build_table_filename()
181
141
  NOTES
182
142
 
183
143
    Uses database and table name, and extension to create
184
 
    a file name in drizzle_data_dir. Database and table
 
144
    a file name in mysql_data_dir. Database and table
185
145
    names are converted from system_charset_info into "fscs".
186
146
    Unless flags indicate a temporary table name.
187
147
    'db' is always converted.
188
148
    'ext' is not converted.
189
149
 
190
 
    The conversion suppression is required for ALTER Table. This
 
150
    The conversion suppression is required for ALTER TABLE. This
191
151
    statement creates intermediate tables. These are regular
192
152
    (non-temporary) tables with a temporary name. Their path names must
193
153
    be derivable from the table name. So we cannot use
194
154
    build_tmptable_filename() for them.
195
155
 
196
156
  RETURN
197
 
    path length on success, 0 on failure
 
157
    path length
198
158
*/
199
159
 
200
 
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
201
 
                          const char *table_name, const char *ext, uint32_t flags)
 
160
uint build_table_filename(char *buff, size_t bufflen, const char *db,
 
161
                          const char *table_name, const char *ext, uint flags)
202
162
{
203
 
  string table_path;
204
163
  char dbbuff[FN_REFLEN];
205
164
  char tbbuff[FN_REFLEN];
 
165
 
 
166
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
 
167
    strnmov(tbbuff, table_name, sizeof(tbbuff));
 
168
  else
 
169
    VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
 
170
 
 
171
  VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
 
172
 
 
173
  char *end = buff + bufflen;
 
174
  /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
 
175
  char *pos = strnmov(buff, mysql_data_home, bufflen);
206
176
  int rootdir_len= strlen(FN_ROOTDIR);
207
 
 
208
 
  if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
209
 
    strncpy(tbbuff, table_name, sizeof(tbbuff));
210
 
  else
211
 
    tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
212
 
 
213
 
  tablename_to_filename(db, dbbuff, sizeof(dbbuff));
214
 
  table_path= drizzle_data_home;
215
 
  int without_rootdir= table_path.length()-rootdir_len;
216
 
 
217
 
  /* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
218
 
  if (without_rootdir >= 0)
219
 
  {
220
 
    char *tmp= (char*)table_path.c_str()+without_rootdir;
221
 
    if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
222
 
      table_path.append(FN_ROOTDIR);
223
 
  }
224
 
 
225
 
  table_path.append(dbbuff);
226
 
  table_path.append(FN_ROOTDIR);
 
177
  if (pos - rootdir_len >= buff &&
 
178
      memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
 
179
    pos= strnmov(pos, FN_ROOTDIR, end - pos);
 
180
  pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
227
181
#ifdef USE_SYMDIR
228
 
  table_path.clear();
 
182
  unpack_dirname(buff, buff);
 
183
  pos= strend(buff);
229
184
#endif
230
 
  table_path.append(tbbuff);
231
 
  table_path.append(ext);
232
 
 
233
 
  if (bufflen < table_path.length())
234
 
    return 0;
235
 
 
236
 
  strcpy(buff, table_path.c_str());
237
 
  return table_path.length();
 
185
  pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
 
186
 
 
187
  return(pos - buff);
238
188
}
239
189
 
240
190
 
241
191
/*
242
 
  Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
 
192
  Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
243
193
 
244
194
  SYNOPSIS
245
195
   build_tmptable_filename()
246
 
     session                    The thread handle.
 
196
     thd                        The thread handle.
247
197
     buff                       Where to write result in my_charset_filename.
248
198
     bufflen                    buff size
249
199
 
250
200
  NOTES
251
201
 
252
202
    Uses current_pid, thread_id, and tmp_table counter to create
253
 
    a file name in drizzle_tmpdir.
 
203
    a file name in mysql_tmpdir.
254
204
 
255
205
  RETURN
256
 
    path length on success, 0 on failure
 
206
    path length
257
207
*/
258
208
 
259
 
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
 
209
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
260
210
{
261
 
  uint32_t length;
262
 
  ostringstream path_str, post_tmpdir_str;
263
 
  string tmp;
264
211
 
265
 
  path_str << drizzle_tmpdir;
266
 
  post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
267
 
  post_tmpdir_str << session->thread_id << session->tmp_table++;
268
 
  tmp= post_tmpdir_str.str();
 
212
  char *p= strnmov(buff, mysql_tmpdir, bufflen);
 
213
  snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
 
214
              tmp_file_prefix, current_pid,
 
215
              thd->thread_id, thd->tmp_table++, reg_ext);
269
216
 
270
217
  if (lower_case_table_names)
271
 
    transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
272
 
 
273
 
  path_str << tmp;
274
 
 
275
 
  if (bufflen < path_str.str().length())
276
 
    length= 0;
277
 
  else
278
 
    length= unpack_filename(buff, path_str.str().c_str());
279
 
 
280
 
  return length;
281
 
}
 
218
  {
 
219
    /* Convert all except tmpdir to lower case */
 
220
    my_casedn_str(files_charset_info, p);
 
221
  }
 
222
 
 
223
  uint length= unpack_filename(buff, buff);
 
224
  return(length);
 
225
}
 
226
 
 
227
/*
 
228
--------------------------------------------------------------------------
 
229
 
 
230
   MODULE: DDL log
 
231
   -----------------
 
232
 
 
233
   This module is used to ensure that we can recover from crashes that occur
 
234
   in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
 
235
   We need to ensure that both t1 and t2 are dropped and not only t1 and
 
236
   also that each table drop is entirely done and not "half-baked".
 
237
 
 
238
   To support this we create log entries for each meta-data statement in the
 
239
   ddl log while we are executing. These entries are dropped when the
 
240
   operation is completed.
 
241
 
 
242
   At recovery those entries that were not completed will be executed.
 
243
 
 
244
   There is only one ddl log in the system and it is protected by a mutex
 
245
   and there is a global struct that contains information about its current
 
246
   state.
 
247
 
 
248
   History:
 
249
   First version written in 2006 by Mikael Ronstrom
 
250
--------------------------------------------------------------------------
 
251
*/
 
252
 
 
253
 
 
254
struct st_global_ddl_log
 
255
{
 
256
  /*
 
257
    We need to adjust buffer size to be able to handle downgrades/upgrades
 
258
    where IO_SIZE has changed. We'll set the buffer size such that we can
 
259
    handle that the buffer size was upto 4 times bigger in the version
 
260
    that wrote the DDL log.
 
261
  */
 
262
  char file_entry_buf[4*IO_SIZE];
 
263
  char file_name_str[FN_REFLEN];
 
264
  char *file_name;
 
265
  DDL_LOG_MEMORY_ENTRY *first_free;
 
266
  DDL_LOG_MEMORY_ENTRY *first_used;
 
267
  uint num_entries;
 
268
  File file_id;
 
269
  uint name_len;
 
270
  uint io_size;
 
271
  bool inited;
 
272
  bool do_release;
 
273
  bool recovery_phase;
 
274
  st_global_ddl_log() : inited(false), do_release(false) {}
 
275
};
 
276
 
 
277
st_global_ddl_log global_ddl_log;
 
278
 
 
279
pthread_mutex_t LOCK_gdl;
 
280
 
 
281
#define DDL_LOG_ENTRY_TYPE_POS 0
 
282
#define DDL_LOG_ACTION_TYPE_POS 1
 
283
#define DDL_LOG_PHASE_POS 2
 
284
#define DDL_LOG_NEXT_ENTRY_POS 4
 
285
#define DDL_LOG_NAME_POS 8
 
286
 
 
287
#define DDL_LOG_NUM_ENTRY_POS 0
 
288
#define DDL_LOG_NAME_LEN_POS 4
 
289
#define DDL_LOG_IO_SIZE_POS 8
 
290
 
 
291
/*
 
292
  Read one entry from ddl log file
 
293
  SYNOPSIS
 
294
    read_ddl_log_file_entry()
 
295
    entry_no                     Entry number to read
 
296
  RETURN VALUES
 
297
    true                         Error
 
298
    false                        Success
 
299
*/
 
300
 
 
301
static bool read_ddl_log_file_entry(uint entry_no)
 
302
{
 
303
  bool error= false;
 
304
  File file_id= global_ddl_log.file_id;
 
305
  uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
 
306
  ssize_t io_size= (ssize_t)global_ddl_log.io_size;
 
307
  
 
308
  if (pread(file_id, file_entry_buf, io_size, io_size * entry_no) != io_size)
 
309
    error= true;
 
310
  return(error);
 
311
}
 
312
 
 
313
 
 
314
/*
 
315
  Write one entry from ddl log file
 
316
  SYNOPSIS
 
317
    write_ddl_log_file_entry()
 
318
    entry_no                     Entry number to read
 
319
  RETURN VALUES
 
320
    true                         Error
 
321
    false                        Success
 
322
*/
 
323
 
 
324
static bool write_ddl_log_file_entry(uint entry_no)
 
325
{
 
326
  bool error= false;
 
327
  File file_id= global_ddl_log.file_id;
 
328
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
329
 
 
330
  if (pwrite(file_id, (uchar*)file_entry_buf,
 
331
                IO_SIZE, IO_SIZE * entry_no) != IO_SIZE)
 
332
    error= true;
 
333
  return(error);
 
334
}
 
335
 
 
336
 
 
337
/*
 
338
  Write ddl log header
 
339
  SYNOPSIS
 
340
    write_ddl_log_header()
 
341
  RETURN VALUES
 
342
    true                      Error
 
343
    false                     Success
 
344
*/
 
345
 
 
346
static bool write_ddl_log_header()
 
347
{
 
348
  uint16 const_var;
 
349
  bool error= false;
 
350
 
 
351
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
 
352
            global_ddl_log.num_entries);
 
353
  const_var= FN_LEN;
 
354
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
 
355
            (ulong) const_var);
 
356
  const_var= IO_SIZE;
 
357
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
 
358
            (ulong) const_var);
 
359
  if (write_ddl_log_file_entry(0UL))
 
360
  {
 
361
    sql_print_error("Error writing ddl log header");
 
362
    return(true);
 
363
  }
 
364
  VOID(sync_ddl_log());
 
365
  return(error);
 
366
}
 
367
 
 
368
 
 
369
/*
 
370
  Create ddl log file name
 
371
  SYNOPSIS
 
372
    create_ddl_log_file_name()
 
373
    file_name                   Filename setup
 
374
  RETURN VALUES
 
375
    NONE
 
376
*/
 
377
 
 
378
static inline void create_ddl_log_file_name(char *file_name)
 
379
{
 
380
  strxmov(file_name, mysql_data_home, "/", "ddl_log.log", NullS);
 
381
}
 
382
 
 
383
 
 
384
/*
 
385
  Read header of ddl log file
 
386
  SYNOPSIS
 
387
    read_ddl_log_header()
 
388
  RETURN VALUES
 
389
    > 0                  Last entry in ddl log
 
390
    0                    No entries in ddl log
 
391
  DESCRIPTION
 
392
    When we read the ddl log header we get information about maximum sizes
 
393
    of names in the ddl log and we also get information about the number
 
394
    of entries in the ddl log.
 
395
*/
 
396
 
 
397
static uint read_ddl_log_header()
 
398
{
 
399
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
400
  char file_name[FN_REFLEN];
 
401
  uint entry_no;
 
402
  bool successful_open= false;
 
403
 
 
404
  create_ddl_log_file_name(file_name);
 
405
  if ((global_ddl_log.file_id= my_open(file_name,
 
406
                                        O_RDWR | O_BINARY, MYF(0))) >= 0)
 
407
  {
 
408
    if (read_ddl_log_file_entry(0UL))
 
409
    {
 
410
      /* Write message into error log */
 
411
      sql_print_error("Failed to read ddl log file in recovery");
 
412
    }
 
413
    else
 
414
      successful_open= true;
 
415
  }
 
416
  entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
 
417
  global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
 
418
  if (successful_open)
 
419
  {
 
420
    global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
 
421
    assert(global_ddl_log.io_size <=
 
422
                sizeof(global_ddl_log.file_entry_buf));
 
423
  }
 
424
  else
 
425
  {
 
426
    entry_no= 0;
 
427
  }
 
428
  global_ddl_log.first_free= NULL;
 
429
  global_ddl_log.first_used= NULL;
 
430
  global_ddl_log.num_entries= 0;
 
431
  VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
 
432
  global_ddl_log.do_release= true;
 
433
  return(entry_no);
 
434
}
 
435
 
 
436
 
 
437
/*
 
438
  Read a ddl log entry
 
439
  SYNOPSIS
 
440
    read_ddl_log_entry()
 
441
    read_entry               Number of entry to read
 
442
    out:entry_info           Information from entry
 
443
  RETURN VALUES
 
444
    true                     Error
 
445
    false                    Success
 
446
  DESCRIPTION
 
447
    Read a specified entry in the ddl log
 
448
*/
 
449
 
 
450
bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
 
451
{
 
452
  char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
 
453
  uint inx;
 
454
  uchar single_char;
 
455
 
 
456
  if (read_ddl_log_file_entry(read_entry))
 
457
  {
 
458
    return(true);
 
459
  }
 
460
  ddl_log_entry->entry_pos= read_entry;
 
461
  single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
 
462
  ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
 
463
  single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
 
464
  ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
 
465
  ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
 
466
  ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
 
467
  ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
 
468
  inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
 
469
  ddl_log_entry->from_name= &file_entry_buf[inx];
 
470
  inx+= global_ddl_log.name_len;
 
471
  ddl_log_entry->handler_name= &file_entry_buf[inx];
 
472
  return(false);
 
473
}
 
474
 
 
475
 
 
476
/*
 
477
  Initialise ddl log
 
478
  SYNOPSIS
 
479
    init_ddl_log()
 
480
 
 
481
  DESCRIPTION
 
482
    Write the header of the ddl log file and length of names. Also set
 
483
    number of entries to zero.
 
484
 
 
485
  RETURN VALUES
 
486
    true                     Error
 
487
    false                    Success
 
488
*/
 
489
 
 
490
static bool init_ddl_log()
 
491
{
 
492
  char file_name[FN_REFLEN];
 
493
 
 
494
  if (global_ddl_log.inited)
 
495
    goto end;
 
496
 
 
497
  global_ddl_log.io_size= IO_SIZE;
 
498
  create_ddl_log_file_name(file_name);
 
499
  if ((global_ddl_log.file_id= my_create(file_name,
 
500
                                         CREATE_MODE,
 
501
                                         O_RDWR | O_TRUNC | O_BINARY,
 
502
                                         MYF(MY_WME))) < 0)
 
503
  {
 
504
    /* Couldn't create ddl log file, this is serious error */
 
505
    sql_print_error("Failed to open ddl log file");
 
506
    return(true);
 
507
  }
 
508
  global_ddl_log.inited= true;
 
509
  if (write_ddl_log_header())
 
510
  {
 
511
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
 
512
    global_ddl_log.inited= false;
 
513
    return(true);
 
514
  }
 
515
 
 
516
end:
 
517
  return(false);
 
518
}
 
519
 
 
520
 
 
521
/*
 
522
  Execute one action in a ddl log entry
 
523
  SYNOPSIS
 
524
    execute_ddl_log_action()
 
525
    ddl_log_entry              Information in action entry to execute
 
526
  RETURN VALUES
 
527
    true                       Error
 
528
    false                      Success
 
529
*/
 
530
 
 
531
static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
 
532
{
 
533
  bool frm_action= false;
 
534
  LEX_STRING handler_name;
 
535
  handler *file= NULL;
 
536
  MEM_ROOT mem_root;
 
537
  int error= true;
 
538
  char to_path[FN_REFLEN];
 
539
  char from_path[FN_REFLEN];
 
540
  handlerton *hton;
 
541
 
 
542
  if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
 
543
  {
 
544
    return(false);
 
545
  }
 
546
  handler_name.str= (char*)ddl_log_entry->handler_name;
 
547
  handler_name.length= strlen(ddl_log_entry->handler_name);
 
548
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); 
 
549
  if (!strcmp(ddl_log_entry->handler_name, reg_ext))
 
550
    frm_action= true;
 
551
  else
 
552
  {
 
553
    plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
 
554
    if (!plugin)
 
555
    {
 
556
      my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
 
557
      goto error;
 
558
    }
 
559
    hton= plugin_data(plugin, handlerton*);
 
560
    file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
 
561
    if (!file)
 
562
    {
 
563
      my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
 
564
      goto error;
 
565
    }
 
566
  }
 
567
  switch (ddl_log_entry->action_type)
 
568
  {
 
569
    case DDL_LOG_REPLACE_ACTION:
 
570
    case DDL_LOG_DELETE_ACTION:
 
571
    {
 
572
      if (ddl_log_entry->phase == 0)
 
573
      {
 
574
        if (frm_action)
 
575
        {
 
576
          strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
 
577
          if ((error= my_delete(to_path, MYF(MY_WME))))
 
578
          {
 
579
            if (my_errno != ENOENT)
 
580
              break;
 
581
          }
 
582
        }
 
583
        else
 
584
        {
 
585
          if ((error= file->ha_delete_table(ddl_log_entry->name)))
 
586
          {
 
587
            if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
 
588
              break;
 
589
          }
 
590
        }
 
591
        if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
 
592
          break;
 
593
        VOID(sync_ddl_log());
 
594
        error= false;
 
595
        if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
 
596
          break;
 
597
      }
 
598
      assert(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
 
599
      /*
 
600
        Fall through and perform the rename action of the replace
 
601
        action. We have already indicated the success of the delete
 
602
        action in the log entry by stepping up the phase.
 
603
      */
 
604
    }
 
605
    case DDL_LOG_RENAME_ACTION:
 
606
    {
 
607
      error= true;
 
608
      if (frm_action)
 
609
      {
 
610
        strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
 
611
        strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
 
612
        if (my_rename(from_path, to_path, MYF(MY_WME)))
 
613
          break;
 
614
      }
 
615
      else
 
616
      {
 
617
        if (file->ha_rename_table(ddl_log_entry->from_name,
 
618
                                  ddl_log_entry->name))
 
619
          break;
 
620
      }
 
621
      if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
 
622
        break;
 
623
      VOID(sync_ddl_log());
 
624
      error= false;
 
625
      break;
 
626
    }
 
627
    default:
 
628
      assert(0);
 
629
      break;
 
630
  }
 
631
  delete file;
 
632
error:
 
633
  free_root(&mem_root, MYF(0)); 
 
634
  return(error);
 
635
}
 
636
 
 
637
 
 
638
/*
 
639
  Get a free entry in the ddl log
 
640
  SYNOPSIS
 
641
    get_free_ddl_log_entry()
 
642
    out:active_entry                A ddl log memory entry returned
 
643
  RETURN VALUES
 
644
    true                       Error
 
645
    false                      Success
 
646
*/
 
647
 
 
648
static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
 
649
                                   bool *write_header)
 
650
{
 
651
  DDL_LOG_MEMORY_ENTRY *used_entry;
 
652
  DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
 
653
 
 
654
  if (global_ddl_log.first_free == NULL)
 
655
  {
 
656
    if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
 
657
                              sizeof(DDL_LOG_MEMORY_ENTRY), MYF(MY_WME))))
 
658
    {
 
659
      sql_print_error("Failed to allocate memory for ddl log free list");
 
660
      return(true);
 
661
    }
 
662
    global_ddl_log.num_entries++;
 
663
    used_entry->entry_pos= global_ddl_log.num_entries;
 
664
    *write_header= true;
 
665
  }
 
666
  else
 
667
  {
 
668
    used_entry= global_ddl_log.first_free;
 
669
    global_ddl_log.first_free= used_entry->next_log_entry;
 
670
    *write_header= false;
 
671
  }
 
672
  /*
 
673
    Move from free list to used list
 
674
  */
 
675
  used_entry->next_log_entry= first_used;
 
676
  used_entry->prev_log_entry= NULL;
 
677
  global_ddl_log.first_used= used_entry;
 
678
  if (first_used)
 
679
    first_used->prev_log_entry= used_entry;
 
680
 
 
681
  *active_entry= used_entry;
 
682
  return(false);
 
683
}
 
684
 
 
685
 
 
686
/*
 
687
  External interface methods for the DDL log Module
 
688
  ---------------------------------------------------
 
689
*/
 
690
 
 
691
/*
 
692
  SYNOPSIS
 
693
    write_ddl_log_entry()
 
694
    ddl_log_entry         Information about log entry
 
695
    out:entry_written     Entry information written into   
 
696
 
 
697
  RETURN VALUES
 
698
    true                      Error
 
699
    false                     Success
 
700
 
 
701
  DESCRIPTION
 
702
    A careful write of the ddl log is performed to ensure that we can
 
703
    handle crashes occurring during CREATE and ALTER TABLE processing.
 
704
*/
 
705
 
 
706
bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
 
707
                         DDL_LOG_MEMORY_ENTRY **active_entry)
 
708
{
 
709
  bool error, write_header;
 
710
 
 
711
  if (init_ddl_log())
 
712
  {
 
713
    return(true);
 
714
  }
 
715
  global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
 
716
                                    (char)DDL_LOG_ENTRY_CODE;
 
717
  global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
 
718
                                    (char)ddl_log_entry->action_type;
 
719
  global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
 
720
  int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
 
721
            ddl_log_entry->next_entry);
 
722
  assert(strlen(ddl_log_entry->name) < FN_LEN);
 
723
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
 
724
          ddl_log_entry->name, FN_LEN - 1);
 
725
  if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
 
726
      ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
 
727
  {
 
728
    assert(strlen(ddl_log_entry->from_name) < FN_LEN);
 
729
    strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
 
730
          ddl_log_entry->from_name, FN_LEN - 1);
 
731
  }
 
732
  else
 
733
    global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
 
734
  assert(strlen(ddl_log_entry->handler_name) < FN_LEN);
 
735
  strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
 
736
          ddl_log_entry->handler_name, FN_LEN - 1);
 
737
  if (get_free_ddl_log_entry(active_entry, &write_header))
 
738
  {
 
739
    return(true);
 
740
  }
 
741
  error= false;
 
742
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
 
743
  {
 
744
    error= true;
 
745
    sql_print_error("Failed to write entry_no = %u",
 
746
                    (*active_entry)->entry_pos);
 
747
  }
 
748
  if (write_header && !error)
 
749
  {
 
750
    VOID(sync_ddl_log());
 
751
    if (write_ddl_log_header())
 
752
      error= true;
 
753
  }
 
754
  if (error)
 
755
    release_ddl_log_memory_entry(*active_entry);
 
756
  return(error);
 
757
}
 
758
 
 
759
 
 
760
/*
 
761
  Write final entry in the ddl log
 
762
  SYNOPSIS
 
763
    write_execute_ddl_log_entry()
 
764
    first_entry                    First entry in linked list of entries
 
765
                                   to execute, if 0 = NULL it means that
 
766
                                   the entry is removed and the entries
 
767
                                   are put into the free list.
 
768
    complete                       Flag indicating we are simply writing
 
769
                                   info about that entry has been completed
 
770
    in:out:active_entry            Entry to execute, 0 = NULL if the entry
 
771
                                   is written first time and needs to be
 
772
                                   returned. In this case the entry written
 
773
                                   is returned in this parameter
 
774
  RETURN VALUES
 
775
    true                           Error
 
776
    false                          Success
 
777
 
 
778
  DESCRIPTION
 
779
    This is the last write in the ddl log. The previous log entries have
 
780
    already been written but not yet synched to disk.
 
781
    We write a couple of log entries that describes action to perform.
 
782
    This entries are set-up in a linked list, however only when a first
 
783
    execute entry is put as the first entry these will be executed.
 
784
    This routine writes this first 
 
785
*/ 
 
786
 
 
787
bool write_execute_ddl_log_entry(uint first_entry,
 
788
                                 bool complete,
 
789
                                 DDL_LOG_MEMORY_ENTRY **active_entry)
 
790
{
 
791
  bool write_header= false;
 
792
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
793
 
 
794
  if (init_ddl_log())
 
795
  {
 
796
    return(true);
 
797
  }
 
798
  if (!complete)
 
799
  {
 
800
    /*
 
801
      We haven't synched the log entries yet, we synch them now before
 
802
      writing the execute entry. If complete is true we haven't written
 
803
      any log entries before, we are only here to write the execute
 
804
      entry to indicate it is done.
 
805
    */
 
806
    VOID(sync_ddl_log());
 
807
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
 
808
  }
 
809
  else
 
810
    file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
 
811
  file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
 
812
  file_entry_buf[DDL_LOG_PHASE_POS]= 0;
 
813
  int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
 
814
  file_entry_buf[DDL_LOG_NAME_POS]= 0;
 
815
  file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
 
816
  file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
 
817
  if (!(*active_entry))
 
818
  {
 
819
    if (get_free_ddl_log_entry(active_entry, &write_header))
 
820
    {
 
821
      return(true);
 
822
    }
 
823
  }
 
824
  if (write_ddl_log_file_entry((*active_entry)->entry_pos))
 
825
  {
 
826
    sql_print_error("Error writing execute entry in ddl log");
 
827
    release_ddl_log_memory_entry(*active_entry);
 
828
    return(true);
 
829
  }
 
830
  VOID(sync_ddl_log());
 
831
  if (write_header)
 
832
  {
 
833
    if (write_ddl_log_header())
 
834
    {
 
835
      release_ddl_log_memory_entry(*active_entry);
 
836
      return(true);
 
837
    }
 
838
  }
 
839
  return(false);
 
840
}
 
841
 
 
842
 
 
843
/*
 
844
  For complex rename operations we need to deactivate individual entries.
 
845
  SYNOPSIS
 
846
    deactivate_ddl_log_entry()
 
847
    entry_no                      Entry position of record to change
 
848
  RETURN VALUES
 
849
    true                         Error
 
850
    false                        Success
 
851
  DESCRIPTION
 
852
    During replace operations where we start with an existing table called
 
853
    t1 and a replacement table called t1#temp or something else and where
 
854
    we want to delete t1 and rename t1#temp to t1 this is not possible to
 
855
    do in a safe manner unless the ddl log is informed of the phases in
 
856
    the change.
 
857
 
 
858
    Delete actions are 1-phase actions that can be ignored immediately after
 
859
    being executed.
 
860
    Rename actions from x to y is also a 1-phase action since there is no
 
861
    interaction with any other handlers named x and y.
 
862
    Replace action where drop y and x -> y happens needs to be a two-phase
 
863
    action. Thus the first phase will drop y and the second phase will
 
864
    rename x -> y.
 
865
*/
 
866
 
 
867
bool deactivate_ddl_log_entry(uint entry_no)
 
868
{
 
869
  char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
 
870
 
 
871
  if (!read_ddl_log_file_entry(entry_no))
 
872
  {
 
873
    if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
 
874
    {
 
875
      if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
 
876
          file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
 
877
          (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
 
878
           file_entry_buf[DDL_LOG_PHASE_POS] == 1))
 
879
        file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
 
880
      else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
 
881
      {
 
882
        assert(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
 
883
        file_entry_buf[DDL_LOG_PHASE_POS]= 1;
 
884
      }
 
885
      else
 
886
      {
 
887
        assert(0);
 
888
      }
 
889
      if (write_ddl_log_file_entry(entry_no))
 
890
      {
 
891
        sql_print_error("Error in deactivating log entry. Position = %u",
 
892
                        entry_no);
 
893
        return(true);
 
894
      }
 
895
    }
 
896
  }
 
897
  else
 
898
  {
 
899
    sql_print_error("Failed in reading entry before deactivating it");
 
900
    return(true);
 
901
  }
 
902
  return(false);
 
903
}
 
904
 
 
905
 
 
906
/*
 
907
  Sync ddl log file
 
908
  SYNOPSIS
 
909
    sync_ddl_log()
 
910
  RETURN VALUES
 
911
    true                      Error
 
912
    false                     Success
 
913
*/
 
914
 
 
915
bool sync_ddl_log()
 
916
{
 
917
  bool error= false;
 
918
 
 
919
  if ((!global_ddl_log.recovery_phase) &&
 
920
      init_ddl_log())
 
921
  {
 
922
    return(true);
 
923
  }
 
924
  if (my_sync(global_ddl_log.file_id, MYF(0)))
 
925
  {
 
926
    /* Write to error log */
 
927
    sql_print_error("Failed to sync ddl log");
 
928
    error= true;
 
929
  }
 
930
  return(error);
 
931
}
 
932
 
 
933
 
 
934
/*
 
935
  Release a log memory entry
 
936
  SYNOPSIS
 
937
    release_ddl_log_memory_entry()
 
938
    log_memory_entry                Log memory entry to release
 
939
  RETURN VALUES
 
940
    NONE
 
941
*/
 
942
 
 
943
void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
 
944
{
 
945
  DDL_LOG_MEMORY_ENTRY *first_free= global_ddl_log.first_free;
 
946
  DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
 
947
  DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
 
948
 
 
949
  global_ddl_log.first_free= log_entry;
 
950
  log_entry->next_log_entry= first_free;
 
951
 
 
952
  if (prev_log_entry)
 
953
    prev_log_entry->next_log_entry= next_log_entry;
 
954
  else
 
955
    global_ddl_log.first_used= next_log_entry;
 
956
  if (next_log_entry)
 
957
    next_log_entry->prev_log_entry= prev_log_entry;
 
958
  return;
 
959
}
 
960
 
 
961
 
 
962
/*
 
963
  Execute one entry in the ddl log. Executing an entry means executing
 
964
  a linked list of actions.
 
965
  SYNOPSIS
 
966
    execute_ddl_log_entry()
 
967
    first_entry                Reference to first action in entry
 
968
  RETURN VALUES
 
969
    true                       Error
 
970
    false                      Success
 
971
*/
 
972
 
 
973
bool execute_ddl_log_entry(THD *thd, uint first_entry)
 
974
{
 
975
  DDL_LOG_ENTRY ddl_log_entry;
 
976
  uint read_entry= first_entry;
 
977
 
 
978
  pthread_mutex_lock(&LOCK_gdl);
 
979
  do
 
980
  {
 
981
    if (read_ddl_log_entry(read_entry, &ddl_log_entry))
 
982
    {
 
983
      /* Write to error log and continue with next log entry */
 
984
      sql_print_error("Failed to read entry = %u from ddl log",
 
985
                      read_entry);
 
986
      break;
 
987
    }
 
988
    assert(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
 
989
                ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
 
990
 
 
991
    if (execute_ddl_log_action(thd, &ddl_log_entry))
 
992
    {
 
993
      /* Write to error log and continue with next log entry */
 
994
      sql_print_error("Failed to execute action for entry = %u from ddl log",
 
995
                      read_entry);
 
996
      break;
 
997
    }
 
998
    read_entry= ddl_log_entry.next_entry;
 
999
  } while (read_entry);
 
1000
  pthread_mutex_unlock(&LOCK_gdl);
 
1001
  return(false);
 
1002
}
 
1003
 
 
1004
 
 
1005
/*
 
1006
  Close the ddl log
 
1007
  SYNOPSIS
 
1008
    close_ddl_log()
 
1009
  RETURN VALUES
 
1010
    NONE
 
1011
*/
 
1012
 
 
1013
static void close_ddl_log()
 
1014
{
 
1015
  if (global_ddl_log.file_id >= 0)
 
1016
  {
 
1017
    VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
 
1018
    global_ddl_log.file_id= (File) -1;
 
1019
  }
 
1020
  return;
 
1021
}
 
1022
 
 
1023
 
 
1024
/*
 
1025
  Execute the ddl log at recovery of MySQL Server
 
1026
  SYNOPSIS
 
1027
    execute_ddl_log_recovery()
 
1028
  RETURN VALUES
 
1029
    NONE
 
1030
*/
 
1031
 
 
1032
void execute_ddl_log_recovery()
 
1033
{
 
1034
  uint num_entries, i;
 
1035
  THD *thd;
 
1036
  DDL_LOG_ENTRY ddl_log_entry;
 
1037
  char file_name[FN_REFLEN];
 
1038
 
 
1039
  /*
 
1040
    Initialise global_ddl_log struct
 
1041
  */
 
1042
  bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
 
1043
  global_ddl_log.inited= false;
 
1044
  global_ddl_log.recovery_phase= true;
 
1045
  global_ddl_log.io_size= IO_SIZE;
 
1046
  global_ddl_log.file_id= (File) -1;
 
1047
 
 
1048
  /*
 
1049
    To be able to run this from boot, we allocate a temporary THD
 
1050
  */
 
1051
  if (!(thd=new THD))
 
1052
    return;
 
1053
  thd->thread_stack= (char*) &thd;
 
1054
  thd->store_globals();
 
1055
 
 
1056
  num_entries= read_ddl_log_header();
 
1057
  for (i= 1; i < num_entries + 1; i++)
 
1058
  {
 
1059
    if (read_ddl_log_entry(i, &ddl_log_entry))
 
1060
    {
 
1061
      sql_print_error("Failed to read entry no = %u from ddl log",
 
1062
                       i);
 
1063
      continue;
 
1064
    }
 
1065
    if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
 
1066
    {
 
1067
      if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
 
1068
      {
 
1069
        /* Real unpleasant scenario but we continue anyways.  */
 
1070
        continue;
 
1071
      }
 
1072
    }
 
1073
  }
 
1074
  close_ddl_log();
 
1075
  create_ddl_log_file_name(file_name);
 
1076
  VOID(my_delete(file_name, MYF(0)));
 
1077
  global_ddl_log.recovery_phase= false;
 
1078
  delete thd;
 
1079
  /* Remember that we don't have a THD */
 
1080
  my_pthread_setspecific_ptr(THR_THD,  0);
 
1081
  return;
 
1082
}
 
1083
 
 
1084
 
 
1085
/*
 
1086
  Release all memory allocated to the ddl log
 
1087
  SYNOPSIS
 
1088
    release_ddl_log()
 
1089
  RETURN VALUES
 
1090
    NONE
 
1091
*/
 
1092
 
 
1093
void release_ddl_log()
 
1094
{
 
1095
  DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
 
1096
  DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
 
1097
 
 
1098
  if (!global_ddl_log.do_release)
 
1099
    return;
 
1100
 
 
1101
  pthread_mutex_lock(&LOCK_gdl);
 
1102
  while (used_list)
 
1103
  {
 
1104
    DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
 
1105
    my_free(used_list, MYF(0));
 
1106
    used_list= tmp;
 
1107
  }
 
1108
  while (free_list)
 
1109
  {
 
1110
    DDL_LOG_MEMORY_ENTRY *tmp= free_list->next_log_entry;
 
1111
    my_free(free_list, MYF(0));
 
1112
    free_list= tmp;
 
1113
  }
 
1114
  close_ddl_log();
 
1115
  global_ddl_log.inited= 0;
 
1116
  pthread_mutex_unlock(&LOCK_gdl);
 
1117
  VOID(pthread_mutex_destroy(&LOCK_gdl));
 
1118
  global_ddl_log.do_release= false;
 
1119
  return;
 
1120
}
 
1121
 
 
1122
 
 
1123
/*
 
1124
---------------------------------------------------------------------------
 
1125
 
 
1126
  END MODULE DDL log
 
1127
  --------------------
 
1128
 
 
1129
---------------------------------------------------------------------------
 
1130
*/
 
1131
 
282
1132
 
283
1133
/*
284
1134
  SYNOPSIS
285
1135
    write_bin_log()
286
 
    session                           Thread object
 
1136
    thd                           Thread object
287
1137
    clear_error                   is clear_error to be called
288
1138
    query                         Query to log
289
1139
    query_length                  Length of query
296
1146
    file
297
1147
*/
298
1148
 
299
 
void write_bin_log(Session *session, bool,
300
 
                   char const *query, size_t query_length)
 
1149
void write_bin_log(THD *thd, bool clear_error,
 
1150
                   char const *query, ulong query_length)
301
1151
{
302
 
  transaction_services.rawStatement(session, query, query_length);
 
1152
  if (mysql_bin_log.is_open())
 
1153
  {
 
1154
    if (clear_error)
 
1155
      thd->clear_error();
 
1156
    thd->binlog_query(THD::STMT_QUERY_TYPE,
 
1157
                      query, query_length, false, false);
 
1158
  }
303
1159
}
304
1160
 
305
1161
 
308
1164
 
309
1165
  SYNOPSIS
310
1166
   mysql_rm_table()
311
 
   session                      Thread handle
 
1167
   thd                  Thread handle
312
1168
   tables               List of tables to delete
313
1169
   if_exists            If 1, don't give error if one table doesn't exists
314
1170
 
327
1183
 
328
1184
*/
329
1185
 
330
 
bool mysql_rm_table(Session *session,TableList *tables, bool if_exists, bool drop_temporary)
 
1186
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
 
1187
                    my_bool drop_temporary)
331
1188
{
332
1189
  bool error, need_start_waiting= false;
333
1190
 
334
1191
  if (tables && tables->schema_table)
335
1192
  {
336
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
1193
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
337
1194
    return(true);
338
1195
  }
339
1196
 
341
1198
 
342
1199
  if (!drop_temporary)
343
1200
  {
344
 
    if (!session->locked_tables &&
345
 
        !(need_start_waiting= !wait_if_global_read_lock(session, 0, 1)))
 
1201
    if (!thd->locked_tables &&
 
1202
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
346
1203
      return(true);
347
1204
  }
348
1205
 
351
1208
    LOCK_open during wait_if_global_read_lock(), other threads could not
352
1209
    close their tables. This would make a pretty deadlock.
353
1210
  */
354
 
  error= mysql_rm_table_part2(session, tables, if_exists, drop_temporary, 0);
 
1211
  error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
355
1212
 
356
1213
  if (need_start_waiting)
357
 
    start_waiting_global_read_lock(session);
 
1214
    start_waiting_global_read_lock(thd);
358
1215
 
359
1216
  if (error)
360
1217
    return(true);
361
 
  session->my_ok();
 
1218
  my_ok(thd);
362
1219
  return(false);
363
1220
}
364
1221
 
367
1224
 
368
1225
  SYNOPSIS
369
1226
    mysql_rm_table_part2()
370
 
    session                     Thread handler
 
1227
    thd                 Thread handler
371
1228
    tables              Tables to drop
372
1229
    if_exists           If set, don't give an error if table doesn't exists.
373
1230
                        In this case we give an warning of level 'NOTE'
374
1231
    drop_temporary      Only drop temporary tables
375
1232
    drop_view           Allow to delete VIEW .frm
376
1233
    dont_log_query      Don't write query to log files. This will also not
377
 
                        generate warnings if the handler files doesn't exists
 
1234
                        generate warnings if the handler files doesn't exists  
378
1235
 
379
1236
  TODO:
380
1237
    When logging to the binary log, we should log
392
1249
   -1   Thread was killed
393
1250
*/
394
1251
 
395
 
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
396
 
                         bool drop_temporary, bool dont_log_query)
 
1252
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
 
1253
                         bool drop_temporary, bool drop_view,
 
1254
                         bool dont_log_query)
397
1255
{
398
 
  TableList *table;
 
1256
  TABLE_LIST *table;
399
1257
  char path[FN_REFLEN], *alias;
400
 
  uint32_t path_length= 0;
 
1258
  uint path_length;
401
1259
  String wrong_tables;
402
1260
  int error= 0;
403
1261
  int non_temp_tables_count= 0;
404
1262
  bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
405
1263
  String built_query;
406
1264
 
407
 
  if (!dont_log_query)
 
1265
  if (thd->current_stmt_binlog_row_based && !dont_log_query)
408
1266
  {
409
1267
    built_query.set_charset(system_charset_info);
410
1268
    if (if_exists)
411
 
      built_query.append("DROP Table IF EXISTS ");
 
1269
      built_query.append("DROP TABLE IF EXISTS ");
412
1270
    else
413
 
      built_query.append("DROP Table ");
 
1271
      built_query.append("DROP TABLE ");
414
1272
  }
415
1273
 
 
1274
  mysql_ha_rm_tables(thd, tables, false);
 
1275
 
416
1276
  pthread_mutex_lock(&LOCK_open);
417
1277
 
418
1278
  /*
429
1289
      table->db_type= share->db_type();
430
1290
  }
431
1291
 
432
 
  if (!drop_temporary && lock_table_names_exclusively(session, tables))
 
1292
  if (!drop_temporary && lock_table_names_exclusively(thd, tables))
433
1293
  {
434
1294
    pthread_mutex_unlock(&LOCK_open);
435
1295
    return(1);
436
1296
  }
437
1297
 
438
1298
  /* Don't give warnings for not found errors, as we already generate notes */
439
 
  session->no_warnings_for_error= 1;
 
1299
  thd->no_warnings_for_error= 1;
440
1300
 
441
1301
  for (table= tables; table; table= table->next_local)
442
1302
  {
443
1303
    char *db=table->db;
444
 
    StorageEngine *table_type;
445
 
 
446
 
    error= drop_temporary_table(session, table);
 
1304
    handlerton *table_type;
 
1305
    enum legacy_db_type frm_db_type;
 
1306
 
 
1307
 
 
1308
    error= drop_temporary_table(thd, table);
447
1309
 
448
1310
    switch (error) {
449
1311
    case  0:
451
1313
      tmp_table_deleted= 1;
452
1314
      continue;
453
1315
    case -1:
 
1316
      assert(thd->in_sub_stmt);
454
1317
      error= 1;
455
1318
      goto err_with_placeholders;
456
1319
    default:
464
1327
      being built.  The string always end in a comma and the comma
465
1328
      will be chopped off before being written to the binary log.
466
1329
      */
467
 
    if (!dont_log_query)
 
1330
    if (thd->current_stmt_binlog_row_based && !dont_log_query)
468
1331
    {
469
1332
      non_temp_tables_count++;
470
1333
      /*
471
1334
        Don't write the database name if it is the current one (or if
472
 
        session->db is NULL).
 
1335
        thd->db is NULL).
473
1336
      */
474
1337
      built_query.append("`");
475
 
      if (session->db == NULL || strcmp(db,session->db) != 0)
 
1338
      if (thd->db == NULL || strcmp(db,thd->db) != 0)
476
1339
      {
477
1340
        built_query.append(db);
478
1341
        built_query.append("`.`");
485
1348
    table_type= table->db_type;
486
1349
    if (!drop_temporary)
487
1350
    {
488
 
      Table *locked_table;
489
 
      abort_locked_tables(session, db, table->table_name);
490
 
      remove_table_from_cache(session, db, table->table_name,
 
1351
      TABLE *locked_table;
 
1352
      abort_locked_tables(thd, db, table->table_name);
 
1353
      remove_table_from_cache(thd, db, table->table_name,
491
1354
                              RTFC_WAIT_OTHER_THREAD_FLAG |
492
1355
                              RTFC_CHECK_KILLED_FLAG);
493
1356
      /*
494
1357
        If the table was used in lock tables, remember it so that
495
1358
        unlock_table_names can free it
496
1359
      */
497
 
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
 
1360
      if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
498
1361
        table->table= locked_table;
499
1362
 
500
 
      if (session->killed)
 
1363
      if (thd->killed)
501
1364
      {
502
1365
        error= -1;
503
1366
        goto err_with_placeholders;
504
1367
      }
505
1368
      alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
506
1369
      /* remove .frm file and engine files */
507
 
      path_length= build_table_filename(path, sizeof(path), db, alias, "",
 
1370
      path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
508
1371
                                        table->internal_tmp_table ?
509
1372
                                        FN_IS_TMP : 0);
510
1373
    }
511
1374
    if (drop_temporary ||
512
 
        ((table_type == NULL && (table_proto_exists(path)!=EEXIST))))
 
1375
        ((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
 
1376
         (!drop_view && mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
513
1377
    {
514
1378
      // Table was not found on disk and table can't be created from engine
515
1379
      if (if_exists)
516
 
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1380
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
517
1381
                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
518
1382
                            table->table_name);
519
1383
      else
521
1385
    }
522
1386
    else
523
1387
    {
524
 
      error= ha_delete_table(session, path, db, table->table_name,
 
1388
      char *end;
 
1389
      if (table_type == NULL)
 
1390
      {
 
1391
        mysql_frm_type(thd, path, &frm_db_type);
 
1392
        table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
 
1393
      }
 
1394
      // Remove extension for delete
 
1395
      *(end= path + path_length - reg_ext_length)= '\0';
 
1396
      error= ha_delete_table(thd, table_type, path, db, table->table_name,
525
1397
                             !dont_log_query);
526
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
527
 
          if_exists)
 
1398
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
 
1399
          (if_exists || table_type == NULL))
528
1400
      {
529
1401
        error= 0;
530
 
        session->clear_error();
 
1402
        thd->clear_error();
531
1403
      }
532
1404
      if (error == HA_ERR_ROW_IS_REFERENCED)
533
1405
      {
537
1409
      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
538
1410
      {
539
1411
        int new_error;
540
 
 
541
 
        if (!(new_error= delete_table_proto_file(path)))
 
1412
        /* Delete the table definition file */
 
1413
        strmov(end,reg_ext);
 
1414
        if (!(new_error=my_delete(path,MYF(MY_WME))))
542
1415
        {
543
1416
          some_tables_deleted=1;
544
1417
          new_error= 0;
558
1431
    on the table name.
559
1432
  */
560
1433
  pthread_mutex_unlock(&LOCK_open);
561
 
  session->thread_specific_used|= tmp_table_deleted;
 
1434
  thd->thread_specific_used|= tmp_table_deleted;
562
1435
  error= 0;
563
1436
  if (wrong_tables.length())
564
1437
  {
566
1439
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
567
1440
                      wrong_tables.c_ptr());
568
1441
    else
569
 
    {
570
1442
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
571
 
    }
572
1443
    error= 1;
573
1444
  }
574
1445
 
576
1447
  {
577
1448
    if (!dont_log_query)
578
1449
    {
579
 
      if ((non_temp_tables_count > 0 && !tmp_table_deleted))
 
1450
      if (!thd->current_stmt_binlog_row_based ||
 
1451
          (non_temp_tables_count > 0 && !tmp_table_deleted))
580
1452
      {
581
1453
        /*
582
1454
          In this case, we are either using statement-based
585
1457
          tables).  In this case, we can write the original query into
586
1458
          the binary log.
587
1459
         */
588
 
        write_bin_log(session, !error, session->query, session->query_length);
 
1460
        write_bin_log(thd, !error, thd->query, thd->query_length);
589
1461
      }
590
 
      else if (non_temp_tables_count > 0 &&
 
1462
      else if (thd->current_stmt_binlog_row_based &&
 
1463
               non_temp_tables_count > 0 &&
591
1464
               tmp_table_deleted)
592
1465
      {
593
1466
        /*
604
1477
        */
605
1478
        built_query.chop();                  // Chop of the last comma
606
1479
        built_query.append(" /* generated by server */");
607
 
        write_bin_log(session, !error, built_query.ptr(), built_query.length());
 
1480
        write_bin_log(thd, !error, built_query.ptr(), built_query.length());
608
1481
      }
609
1482
      /*
610
1483
        The remaining cases are:
618
1491
  }
619
1492
  pthread_mutex_lock(&LOCK_open);
620
1493
err_with_placeholders:
621
 
  unlock_table_names(session, tables, (TableList*) 0);
 
1494
  unlock_table_names(thd, tables, (TABLE_LIST*) 0);
622
1495
  pthread_mutex_unlock(&LOCK_open);
623
 
  session->no_warnings_for_error= 0;
 
1496
  thd->no_warnings_for_error= 0;
624
1497
  return(error);
625
1498
}
626
1499
 
630
1503
 
631
1504
  SYNOPSIS
632
1505
    quick_rm_table()
633
 
      base                      The StorageEngine handle.
 
1506
      base                      The handlerton handle.
634
1507
      db                        The database name.
635
1508
      table_name                The table name.
636
1509
      flags                     flags for build_table_filename().
640
1513
    != 0        Error
641
1514
*/
642
1515
 
643
 
bool quick_rm_table(StorageEngine *,const char *db,
644
 
                    const char *table_name, uint32_t flags)
 
1516
bool quick_rm_table(handlerton *base,const char *db,
 
1517
                    const char *table_name, uint flags)
645
1518
{
646
1519
  char path[FN_REFLEN];
647
1520
  bool error= 0;
648
1521
 
649
 
  build_table_filename(path, sizeof(path), db, table_name, "", flags);
650
 
 
651
 
  error= delete_table_proto_file(path);
652
 
 
653
 
  return(ha_delete_table(current_session, path, db, table_name, 0) ||
 
1522
  uint path_length= build_table_filename(path, sizeof(path),
 
1523
                                         db, table_name, reg_ext, flags);
 
1524
  if (my_delete(path,MYF(0)))
 
1525
    error= 1; /* purecov: inspected */
 
1526
  path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
 
1527
  return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
654
1528
              error);
655
1529
}
656
1530
 
670
1544
static int sort_keys(KEY *a, KEY *b)
671
1545
{
672
1546
  ulong a_flags= a->flags, b_flags= b->flags;
673
 
 
 
1547
  
674
1548
  if (a_flags & HA_NOSAME)
675
1549
  {
676
1550
    if (!(b_flags & HA_NOSAME))
680
1554
      /* Sort NOT NULL keys before other keys */
681
1555
      return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
682
1556
    }
683
 
    if (is_primary_key(a))
 
1557
    if (a->name == primary_key_name)
684
1558
      return -1;
685
 
    if (is_primary_key(b))
 
1559
    if (b->name == primary_key_name)
686
1560
      return 1;
687
1561
    /* Sort keys don't containing partial segments before others */
688
1562
    if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
721
1595
 
722
1596
bool check_duplicates_in_interval(const char *set_or_name,
723
1597
                                  const char *name, TYPELIB *typelib,
724
 
                                  const CHARSET_INFO * const cs, unsigned int *dup_val_count)
 
1598
                                  CHARSET_INFO *cs, unsigned int *dup_val_count)
725
1599
{
726
1600
  TYPELIB tmp= *typelib;
727
1601
  const char **cur_value= typelib->type_names;
728
1602
  unsigned int *cur_length= typelib->type_lengths;
729
 
  *dup_val_count= 0;
730
 
 
 
1603
  *dup_val_count= 0;  
 
1604
  
731
1605
  for ( ; tmp.count > 1; cur_value++, cur_length++)
732
1606
  {
733
1607
    tmp.type_names++;
762
1636
  RETURN VALUES
763
1637
    void
764
1638
*/
765
 
void calculate_interval_lengths(const CHARSET_INFO * const cs, TYPELIB *interval,
766
 
                                uint32_t *max_length, uint32_t *tot_length)
 
1639
void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
 
1640
                                uint32 *max_length, uint32 *tot_length)
767
1641
{
768
1642
  const char **pos;
769
 
  uint32_t *len;
 
1643
  uint *len;
770
1644
  *max_length= *tot_length= 0;
771
1645
  for (pos= interval->type_names, len= interval->type_lengths;
772
1646
       *pos ; pos++, len++)
773
1647
  {
774
 
    uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
 
1648
    uint length= cs->cset->numchars(cs, *pos, *pos + *len);
775
1649
    *tot_length+= length;
776
 
    set_if_bigger(*max_length, (uint32_t)length);
 
1650
    set_if_bigger(*max_length, (uint32)length);
777
1651
  }
778
1652
}
779
1653
 
797
1671
   1    Error
798
1672
*/
799
1673
 
800
 
int prepare_create_field(Create_field *sql_field,
801
 
                         uint32_t *blob_columns,
 
1674
int prepare_create_field(Create_field *sql_field, 
 
1675
                         uint *blob_columns,
802
1676
                         int *timestamps, int *timestamps_with_niladic,
803
 
                         int64_t )
 
1677
                         longlong table_flags __attribute__((__unused__)))
804
1678
{
805
1679
  unsigned int dup_val_count;
806
1680
 
811
1685
  assert(sql_field->charset);
812
1686
 
813
1687
  switch (sql_field->sql_type) {
814
 
  case DRIZZLE_TYPE_BLOB:
 
1688
  case MYSQL_TYPE_BLOB:
815
1689
    sql_field->pack_flag=FIELDFLAG_BLOB |
816
1690
      pack_length_to_packflag(sql_field->pack_length -
817
1691
                              portable_sizeof_char_ptr);
818
1692
    if (sql_field->charset->state & MY_CS_BINSORT)
819
1693
      sql_field->pack_flag|=FIELDFLAG_BINARY;
820
1694
    sql_field->length=8;                        // Unireg field length
 
1695
    sql_field->unireg_check=Field::BLOB_FIELD;
821
1696
    (*blob_columns)++;
822
1697
    break;
823
 
  case DRIZZLE_TYPE_VARCHAR:
 
1698
  case MYSQL_TYPE_VARCHAR:
 
1699
  case MYSQL_TYPE_STRING:
824
1700
    sql_field->pack_flag=0;
825
1701
    if (sql_field->charset->state & MY_CS_BINSORT)
826
1702
      sql_field->pack_flag|=FIELDFLAG_BINARY;
827
1703
    break;
828
 
  case DRIZZLE_TYPE_ENUM:
 
1704
  case MYSQL_TYPE_ENUM:
829
1705
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
830
1706
      FIELDFLAG_INTERVAL;
831
1707
    if (sql_field->charset->state & MY_CS_BINSORT)
832
1708
      sql_field->pack_flag|=FIELDFLAG_BINARY;
 
1709
    sql_field->unireg_check=Field::INTERVAL_FIELD;
833
1710
    if (check_duplicates_in_interval("ENUM",sql_field->field_name,
834
1711
                                 sql_field->interval,
835
1712
                                     sql_field->charset, &dup_val_count))
836
1713
      return(1);
837
1714
    break;
838
 
  case DRIZZLE_TYPE_DATE:  // Rest of string types
839
 
  case DRIZZLE_TYPE_DATETIME:
840
 
  case DRIZZLE_TYPE_NULL:
841
 
    sql_field->pack_flag=f_settype((uint32_t) sql_field->sql_type);
842
 
    break;
843
 
  case DRIZZLE_TYPE_NEWDECIMAL:
 
1715
  case MYSQL_TYPE_SET:
 
1716
    sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
 
1717
      FIELDFLAG_BITFIELD;
 
1718
    if (sql_field->charset->state & MY_CS_BINSORT)
 
1719
      sql_field->pack_flag|=FIELDFLAG_BINARY;
 
1720
    sql_field->unireg_check=Field::BIT_FIELD;
 
1721
    if (check_duplicates_in_interval("SET",sql_field->field_name,
 
1722
                                 sql_field->interval,
 
1723
                                     sql_field->charset, &dup_val_count))
 
1724
      return(1);
 
1725
    /* Check that count of unique members is not more then 64 */
 
1726
    if (sql_field->interval->count -  dup_val_count > sizeof(longlong)*8)
 
1727
    {
 
1728
       my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
 
1729
       return(1);
 
1730
    }
 
1731
    break;
 
1732
  case MYSQL_TYPE_NEWDATE:  // Rest of string types
 
1733
  case MYSQL_TYPE_TIME:
 
1734
  case MYSQL_TYPE_DATETIME:
 
1735
  case MYSQL_TYPE_NULL:
 
1736
    sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
 
1737
    break;
 
1738
  case MYSQL_TYPE_NEWDECIMAL:
844
1739
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
845
1740
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
846
1741
                           FIELDFLAG_DECIMAL) |
847
 
                          (sql_field->flags & DECIMAL_FLAG ?  FIELDFLAG_DECIMAL_POSITION : 0) |
 
1742
                          (sql_field->flags & ZEROFILL_FLAG ?
 
1743
                           FIELDFLAG_ZEROFILL : 0) |
848
1744
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
849
1745
    break;
850
 
  case DRIZZLE_TYPE_TIMESTAMP:
 
1746
  case MYSQL_TYPE_TIMESTAMP:
851
1747
    /* We should replace old TIMESTAMP fields with their newer analogs */
852
1748
    if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
853
1749
    {
868
1764
    sql_field->pack_flag=(FIELDFLAG_NUMBER |
869
1765
                          (sql_field->flags & UNSIGNED_FLAG ? 0 :
870
1766
                           FIELDFLAG_DECIMAL) |
871
 
                          f_settype((uint32_t) sql_field->sql_type) |
 
1767
                          (sql_field->flags & ZEROFILL_FLAG ?
 
1768
                           FIELDFLAG_ZEROFILL : 0) |
 
1769
                          f_settype((uint) sql_field->sql_type) |
872
1770
                          (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
873
1771
    break;
874
1772
  }
875
 
  if (!(sql_field->flags & NOT_NULL_FLAG) ||
876
 
      (sql_field->vcol_info)) /* Make virtual columns always allow NULL values */
 
1773
  if (!(sql_field->flags & NOT_NULL_FLAG))
877
1774
    sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
878
1775
  if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
879
1776
    sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
885
1782
 
886
1783
  SYNOPSIS
887
1784
    mysql_prepare_create_table()
888
 
      session                       Thread object.
 
1785
      thd                       Thread object.
889
1786
      create_info               Create information (like MAX_ROWS).
890
1787
      alter_info                List of columns and indexes to create
891
1788
      tmp_table                 If a temporary table is to be created.
907
1804
*/
908
1805
 
909
1806
static int
910
 
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
 
1807
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
911
1808
                           Alter_info *alter_info,
912
1809
                           bool tmp_table,
913
 
                               uint32_t *db_options,
 
1810
                               uint *db_options,
914
1811
                               handler *file, KEY **key_info_buffer,
915
 
                               uint32_t *key_count, int select_field_count)
 
1812
                               uint *key_count, int select_field_count)
916
1813
{
917
1814
  const char    *key_name;
918
1815
  Create_field  *sql_field,*dup_field;
925
1822
  int           select_field_pos,auto_increment=0;
926
1823
  List_iterator<Create_field> it(alter_info->create_list);
927
1824
  List_iterator<Create_field> it2(alter_info->create_list);
928
 
  uint32_t total_uneven_bit_length= 0;
 
1825
  uint total_uneven_bit_length= 0;
929
1826
 
930
1827
  select_field_pos= alter_info->create_list.elements - select_field_count;
931
1828
  null_fields=blob_columns=0;
934
1831
 
935
1832
  for (field_no=0; (sql_field=it++) ; field_no++)
936
1833
  {
937
 
    const CHARSET_INFO *save_cs;
 
1834
    CHARSET_INFO *save_cs;
938
1835
 
939
1836
    /*
940
1837
      Initialize length from its original value (number of characters),
945
1842
    if (!sql_field->charset)
946
1843
      sql_field->charset= create_info->default_table_charset;
947
1844
    /*
948
 
      table_charset is set in ALTER Table if we want change character set
 
1845
      table_charset is set in ALTER TABLE if we want change character set
949
1846
      for all varchar/char columns.
950
1847
      But the table charset must not affect the BLOB fields, so don't
951
1848
      allow to change my_charset_bin to somethig else.
955
1852
 
956
1853
    save_cs= sql_field->charset;
957
1854
    if ((sql_field->flags & BINCMP_FLAG) &&
958
 
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, MY_CS_BINSORT)))
 
1855
        !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
 
1856
                                                    MY_CS_BINSORT,MYF(0))))
959
1857
    {
960
1858
      char tmp[64];
961
 
      char *tmp_pos= tmp;
962
 
      strncpy(tmp_pos, save_cs->csname, sizeof(tmp)-4);
963
 
      tmp_pos+= strlen(tmp);
964
 
      strncpy(tmp_pos, STRING_WITH_LEN("_bin"));
 
1859
      strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
 
1860
              STRING_WITH_LEN("_bin"));
965
1861
      my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
966
1862
      return(true);
967
1863
    }
970
1866
      Convert the default value from client character
971
1867
      set into the column character set if necessary.
972
1868
    */
973
 
    if (sql_field->def &&
 
1869
    if (sql_field->def && 
974
1870
        save_cs != sql_field->def->collation.collation &&
975
 
        (sql_field->sql_type == DRIZZLE_TYPE_ENUM))
 
1871
        (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
 
1872
         sql_field->sql_type == MYSQL_TYPE_STRING ||
 
1873
         sql_field->sql_type == MYSQL_TYPE_SET ||
 
1874
         sql_field->sql_type == MYSQL_TYPE_ENUM))
976
1875
    {
977
1876
      /*
978
1877
        Starting from 5.1 we work here with a copy of Create_field
994
1893
      }
995
1894
    }
996
1895
 
997
 
    if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
 
1896
    if (sql_field->sql_type == MYSQL_TYPE_SET ||
 
1897
        sql_field->sql_type == MYSQL_TYPE_ENUM)
998
1898
    {
999
 
      uint32_t dummy;
1000
 
      const CHARSET_INFO * const cs= sql_field->charset;
 
1899
      uint32 dummy;
 
1900
      CHARSET_INFO *cs= sql_field->charset;
1001
1901
      TYPELIB *interval= sql_field->interval;
1002
1902
 
1003
1903
      /*
1012
1912
          occupied memory at the same time when we free this
1013
1913
          sql_field -- at the end of execution.
1014
1914
        */
1015
 
        interval= sql_field->interval= typelib(session->mem_root,
 
1915
        interval= sql_field->interval= typelib(thd->mem_root,
1016
1916
                                               sql_field->interval_list);
1017
1917
        List_iterator<String> int_it(sql_field->interval_list);
1018
1918
        String conv, *tmp;
1019
1919
        char comma_buf[4];
1020
 
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
1021
 
                                          (unsigned char*) comma_buf +
 
1920
        int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
 
1921
                                          (uchar*) comma_buf + 
1022
1922
                                          sizeof(comma_buf));
1023
1923
        assert(comma_length > 0);
1024
 
        for (uint32_t i= 0; (tmp= int_it++); i++)
 
1924
        for (uint i= 0; (tmp= int_it++); i++)
1025
1925
        {
1026
 
          uint32_t lengthsp;
 
1926
          uint lengthsp;
1027
1927
          if (String::needs_conversion(tmp->length(), tmp->charset(),
1028
1928
                                       cs, &dummy))
1029
1929
          {
1030
 
            uint32_t cnv_errs;
 
1930
            uint cnv_errs;
1031
1931
            conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
1032
 
            interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
 
1932
            interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
1033
1933
                                                  conv.length());
1034
1934
            interval->type_lengths[i]= conv.length();
1035
1935
          }
1038
1938
          lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
1039
1939
                                       interval->type_lengths[i]);
1040
1940
          interval->type_lengths[i]= lengthsp;
1041
 
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
 
1941
          ((uchar *)interval->type_names[i])[lengthsp]= '\0';
 
1942
          if (sql_field->sql_type == MYSQL_TYPE_SET)
 
1943
          {
 
1944
            if (cs->coll->instr(cs, interval->type_names[i], 
 
1945
                                interval->type_lengths[i], 
 
1946
                                comma_buf, comma_length, NULL, 0))
 
1947
            {
 
1948
              my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
 
1949
              return(true);
 
1950
            }
 
1951
          }
1042
1952
        }
1043
1953
        sql_field->interval_list.empty(); // Don't need interval_list anymore
1044
1954
      }
1045
1955
 
1046
 
      /* DRIZZLE_TYPE_ENUM */
1047
 
      {
1048
 
        uint32_t field_length;
1049
 
        assert(sql_field->sql_type == DRIZZLE_TYPE_ENUM);
 
1956
      if (sql_field->sql_type == MYSQL_TYPE_SET)
 
1957
      {
 
1958
        uint32 field_length;
 
1959
        if (sql_field->def != NULL)
 
1960
        {
 
1961
          char *not_used;
 
1962
          uint not_used2;
 
1963
          bool not_found= 0;
 
1964
          String str, *def= sql_field->def->val_str(&str);
 
1965
          if (def == NULL) /* SQL "NULL" maps to NULL */
 
1966
          {
 
1967
            if ((sql_field->flags & NOT_NULL_FLAG) != 0)
 
1968
            {
 
1969
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
 
1970
              return(true);
 
1971
            }
 
1972
 
 
1973
            /* else, NULL is an allowed value */
 
1974
            (void) find_set(interval, NULL, 0,
 
1975
                            cs, &not_used, &not_used2, &not_found);
 
1976
          }
 
1977
          else /* not NULL */
 
1978
          {
 
1979
            (void) find_set(interval, def->ptr(), def->length(),
 
1980
                            cs, &not_used, &not_used2, &not_found);
 
1981
          }
 
1982
 
 
1983
          if (not_found)
 
1984
          {
 
1985
            my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
 
1986
            return(true);
 
1987
          }
 
1988
        }
 
1989
        calculate_interval_lengths(cs, interval, &dummy, &field_length);
 
1990
        sql_field->length= field_length + (interval->count - 1);
 
1991
      }
 
1992
      else  /* MYSQL_TYPE_ENUM */
 
1993
      {
 
1994
        uint32 field_length;
 
1995
        assert(sql_field->sql_type == MYSQL_TYPE_ENUM);
1050
1996
        if (sql_field->def != NULL)
1051
1997
        {
1052
1998
          String str, *def= sql_field->def->val_str(&str);
1059
2005
            }
1060
2006
 
1061
2007
            /* else, the defaults yield the correct length for NULLs. */
1062
 
          }
 
2008
          } 
1063
2009
          else /* not NULL */
1064
2010
          {
1065
2011
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
1073
2019
        calculate_interval_lengths(cs, interval, &field_length, &dummy);
1074
2020
        sql_field->length= field_length;
1075
2021
      }
1076
 
      set_if_smaller(sql_field->length, (uint32_t)MAX_FIELD_WIDTH-1);
 
2022
      set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
1077
2023
    }
1078
2024
 
1079
2025
    sql_field->create_length_to_internal_length();
1080
 
    if (prepare_blob_field(session, sql_field))
 
2026
    if (prepare_blob_field(thd, sql_field))
1081
2027
      return(true);
1082
2028
 
1083
2029
    if (!(sql_field->flags & NOT_NULL_FLAG))
1119
2065
          sql_field->decimals=          dup_field->decimals;
1120
2066
          sql_field->create_length_to_internal_length();
1121
2067
          sql_field->unireg_check=      dup_field->unireg_check;
1122
 
          /*
 
2068
          /* 
1123
2069
            We're making one field from two, the result field will have
1124
2070
            dup_field->flags as flags. If we've incremented null_fields
1125
2071
            because of sql_field->flags, decrement it back.
1128
2074
            null_fields--;
1129
2075
          sql_field->flags=             dup_field->flags;
1130
2076
          sql_field->interval=          dup_field->interval;
1131
 
          sql_field->vcol_info=         dup_field->vcol_info;
1132
 
          sql_field->is_stored=      dup_field->is_stored;
1133
2077
          it2.remove();                 // Remove first (create) definition
1134
2078
          select_field_pos--;
1135
2079
          break;
1138
2082
    }
1139
2083
    /* Don't pack rows in old tables if the user has requested this */
1140
2084
    if ((sql_field->flags & BLOB_FLAG) ||
1141
 
        (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
2085
        (sql_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
1142
2086
      (*db_options)|= HA_OPTION_PACK_RECORD;
1143
2087
    it2.rewind();
1144
2088
  }
1152
2096
  {
1153
2097
    assert(sql_field->charset != 0);
1154
2098
 
1155
 
    if (prepare_create_field(sql_field, &blob_columns,
 
2099
    if (prepare_create_field(sql_field, &blob_columns, 
1156
2100
                             &timestamps, &timestamps_with_niladic,
1157
2101
                             file->ha_table_flags()))
1158
2102
      return(true);
1159
 
    if (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
 
2103
    if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
1160
2104
      create_info->varchar= true;
1161
2105
    sql_field->offset= record_offset;
1162
2106
    if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
1163
2107
      auto_increment++;
1164
 
    /*
1165
 
          For now skip fields that are not physically stored in the database
1166
 
          (virtual fields) and update their offset later
1167
 
          (see the next loop).
1168
 
        */
1169
 
    if (sql_field->is_stored)
1170
 
      record_offset+= sql_field->pack_length;
1171
 
  }
1172
 
  /* Update virtual fields' offset */
1173
 
  it.rewind();
1174
 
  while ((sql_field=it++))
1175
 
  {
1176
 
    if (not sql_field->is_stored)
1177
 
    {
1178
 
      sql_field->offset= record_offset;
1179
 
      record_offset+= sql_field->pack_length;
1180
 
    }
 
2108
    record_offset+= sql_field->pack_length;
1181
2109
  }
1182
2110
  if (timestamps_with_niladic > 1)
1183
2111
  {
1209
2137
 
1210
2138
  List_iterator<Key> key_iterator(alter_info->key_list);
1211
2139
  List_iterator<Key> key_iterator2(alter_info->key_list);
1212
 
  uint32_t key_parts=0, fk_key_count=0;
 
2140
  uint key_parts=0, fk_key_count=0;
1213
2141
  bool primary_key=0,unique_key=0;
1214
2142
  Key *key, *key2;
1215
 
  uint32_t tmp, key_number;
 
2143
  uint tmp, key_number;
1216
2144
  /* special marker for keys to be ignored */
1217
2145
  static char ignore_key[1];
1218
2146
 
1224
2152
    if (key->type == Key::FOREIGN_KEY)
1225
2153
    {
1226
2154
      fk_key_count++;
1227
 
      if (((Foreign_key *)key)->validate(alter_info->create_list))
1228
 
        return true;
1229
2155
      Foreign_key *fk_key= (Foreign_key*) key;
1230
2156
      if (fk_key->ref_columns.elements &&
1231
2157
          fk_key->ref_columns.elements != fk_key->columns.elements)
1282
2208
    else
1283
2209
      (*key_count)--;
1284
2210
    if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
1285
 
        is_primary_key_name(key->name.str))
 
2211
        !my_strcasecmp(system_charset_info,key->name.str, primary_key_name))
1286
2212
    {
1287
2213
      my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
1288
2214
      return(true);
1304
2230
  key_number=0;
1305
2231
  for (; (key=key_iterator++) ; key_number++)
1306
2232
  {
1307
 
    uint32_t key_length=0;
 
2233
    uint key_length=0;
1308
2234
    Key_part_spec *column;
1309
2235
 
1310
2236
    if (key->name.str == ignore_key)
1331
2257
    if (key->generated)
1332
2258
      key_info->flags|= HA_GENERATED_KEY;
1333
2259
 
1334
 
    key_info->key_parts=(uint8_t) key->columns.elements;
 
2260
    key_info->key_parts=(uint8) key->columns.elements;
1335
2261
    key_info->key_part=key_part_info;
1336
2262
    key_info->usable_key_parts= key_number;
1337
2263
    key_info->algorithm= key->key_create_info.algorithm;
1348
2274
    if (key_info->block_size)
1349
2275
      key_info->flags|= HA_USES_BLOCK_SIZE;
1350
2276
 
1351
 
    uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
2277
    uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
1352
2278
                                           key->key_create_info.comment.str,
1353
2279
                                           key->key_create_info.comment.str +
1354
2280
                                           key->key_create_info.comment.length,
1358
2284
    {
1359
2285
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
1360
2286
               key->key_create_info.comment.str,"INDEX COMMENT",
1361
 
               (uint32_t) INDEX_COMMENT_MAXLEN);
 
2287
               (uint) INDEX_COMMENT_MAXLEN);
1362
2288
      return(-1);
1363
2289
    }
1364
2290
 
1370
2296
    }
1371
2297
 
1372
2298
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
1373
 
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
 
2299
    for (uint column_nr=0 ; (column=cols++) ; column_nr++)
1374
2300
    {
1375
 
      uint32_t length;
 
2301
      uint length;
1376
2302
      Key_part_spec *dup_column;
1377
2303
 
1378
2304
      it.rewind();
1415
2341
            return(true);
1416
2342
          }
1417
2343
        }
1418
 
        if (not sql_field->is_stored)
1419
 
        {
1420
 
          /* Key fields must always be physically stored. */
1421
 
          my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0));
1422
 
          return(true);
1423
 
        }
1424
 
        if (key->type == Key::PRIMARY && sql_field->vcol_info)
1425
 
        {
1426
 
          my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0));
1427
 
          return(true);
1428
 
        }
1429
2344
        if (!(sql_field->flags & NOT_NULL_FLAG))
1430
2345
        {
1431
2346
          if (key->type == Key::PRIMARY)
1453
2368
      }
1454
2369
 
1455
2370
      key_part_info->fieldnr= field;
1456
 
      key_part_info->offset=  (uint16_t) sql_field->offset;
 
2371
      key_part_info->offset=  (uint16) sql_field->offset;
1457
2372
      key_part_info->key_type=sql_field->pack_flag;
1458
2373
      length= sql_field->key_length;
1459
2374
 
1464
2379
          if ((length=column->length) > max_key_length ||
1465
2380
              length > file->max_key_part_length())
1466
2381
          {
1467
 
            length=cmin(max_key_length, file->max_key_part_length());
 
2382
            length=min(max_key_length, file->max_key_part_length());
1468
2383
            if (key->type == Key::MULTIPLE)
1469
2384
            {
1470
2385
              /* not a critical problem */
1471
 
              char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
2386
              char warn_buff[MYSQL_ERRMSG_SIZE];
1472
2387
              snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1473
2388
                       length);
1474
 
              push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2389
              push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1475
2390
                           ER_TOO_LONG_KEY, warn_buff);
1476
2391
              /* Align key length to multibyte char boundary */
1477
2392
              length-= length % sql_field->charset->mbmaxlen;
1507
2422
        if (key->type == Key::MULTIPLE)
1508
2423
        {
1509
2424
          /* not a critical problem */
1510
 
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
2425
          char warn_buff[MYSQL_ERRMSG_SIZE];
1511
2426
          snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1512
2427
                   length);
1513
 
          push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2428
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1514
2429
                       ER_TOO_LONG_KEY, warn_buff);
1515
2430
          /* Align key length to multibyte char boundary */
1516
2431
          length-= length % sql_field->charset->mbmaxlen;
1521
2436
          return(true);
1522
2437
        }
1523
2438
      }
1524
 
      key_part_info->length=(uint16_t) length;
 
2439
      key_part_info->length=(uint16) length;
1525
2440
      /* Use packed keys for long strings on the first column */
1526
2441
      if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
1527
2442
          (length >= KEY_DEFAULT_PACK_LENGTH &&
1528
 
           (sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
 
2443
           (sql_field->sql_type == MYSQL_TYPE_STRING ||
 
2444
            sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
1529
2445
            sql_field->pack_flag & FIELDFLAG_BLOB)))
1530
2446
      {
1531
2447
        if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
1532
 
            sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
 
2448
            sql_field->sql_type == MYSQL_TYPE_VARCHAR)
1533
2449
          key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
1534
2450
        else
1535
2451
          key_info->flags|= HA_PACK_KEY;
1552
2468
                       MYF(0));
1553
2469
            return(true);
1554
2470
          }
1555
 
          static const char pkey_name[]= "PRIMARY";
1556
 
          key_name=pkey_name;
 
2471
          key_name=primary_key_name;
1557
2472
          primary_key=1;
1558
2473
        }
1559
2474
        else if (!(key_name= key->name.str))
1574
2489
    }
1575
2490
    if (!(key_info->flags & HA_NULL_PART_KEY))
1576
2491
      unique_key=1;
1577
 
    key_info->key_length=(uint16_t) key_length;
 
2492
    key_info->key_length=(uint16) key_length;
1578
2493
    if (key_length > max_key_length)
1579
2494
    {
1580
2495
      my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1594
2509
    return(true);
1595
2510
  }
1596
2511
  /* Sort keys in optimized order */
1597
 
  my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KEY),
 
2512
  my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
1598
2513
           (qsort_cmp) sort_keys);
1599
2514
  create_info->null_bits= null_fields;
1600
2515
 
1604
2519
  {
1605
2520
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1606
2521
 
1607
 
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
 
2522
    if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
1608
2523
        !sql_field->def &&
1609
 
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
 
2524
        sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
1610
2525
        (sql_field->flags & NOT_NULL_FLAG) &&
1611
2526
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1612
2527
    {
1632
2547
  return(false);
1633
2548
}
1634
2549
 
 
2550
 
 
2551
/*
 
2552
  Set table default charset, if not set
 
2553
 
 
2554
  SYNOPSIS
 
2555
    set_table_default_charset()
 
2556
    create_info        Table create information
 
2557
 
 
2558
  DESCRIPTION
 
2559
    If the table character set was not given explicitely,
 
2560
    let's fetch the database default character set and
 
2561
    apply it to the table.
 
2562
*/
 
2563
 
 
2564
static void set_table_default_charset(THD *thd,
 
2565
                                      HA_CREATE_INFO *create_info, char *db)
 
2566
{
 
2567
  /*
 
2568
    If the table character set was not given explicitly,
 
2569
    let's fetch the database default character set and
 
2570
    apply it to the table.
 
2571
  */
 
2572
  if (!create_info->default_table_charset)
 
2573
  {
 
2574
    HA_CREATE_INFO db_info;
 
2575
 
 
2576
    load_db_opt_by_name(thd, db, &db_info);
 
2577
 
 
2578
    create_info->default_table_charset= db_info.default_table_charset;
 
2579
  }
 
2580
}
 
2581
 
 
2582
 
1635
2583
/*
1636
2584
  Extend long VARCHAR fields to blob & prepare field if it's a blob
1637
2585
 
1645
2593
        In this case the error is given
1646
2594
*/
1647
2595
 
1648
 
static bool prepare_blob_field(Session *,
 
2596
static bool prepare_blob_field(THD *thd __attribute__((__unused__)),
1649
2597
                               Create_field *sql_field)
1650
2598
{
1651
2599
 
1656
2604
             MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1657
2605
    return(1);
1658
2606
  }
1659
 
 
 
2607
    
1660
2608
  if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1661
2609
  {
1662
 
    if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
 
2610
    if (sql_field->sql_type == MYSQL_TYPE_BLOB)
1663
2611
    {
1664
2612
      /* The user has given a length to the blob column */
1665
2613
      sql_field->sql_type= get_blob_type_from_length(sql_field->length);
1672
2620
 
1673
2621
 
1674
2622
/*
 
2623
  Preparation of Create_field for SP function return values.
 
2624
  Based on code used in the inner loop of mysql_prepare_create_table()
 
2625
  above.
 
2626
 
 
2627
  SYNOPSIS
 
2628
    sp_prepare_create_field()
 
2629
    thd                 Thread object
 
2630
    sql_field           Field to prepare
 
2631
 
 
2632
  DESCRIPTION
 
2633
    Prepares the field structures for field creation.
 
2634
 
 
2635
*/
 
2636
 
 
2637
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
 
2638
{
 
2639
  if (sql_field->sql_type == MYSQL_TYPE_SET ||
 
2640
      sql_field->sql_type == MYSQL_TYPE_ENUM)
 
2641
  {
 
2642
    uint32 field_length, dummy;
 
2643
    if (sql_field->sql_type == MYSQL_TYPE_SET)
 
2644
    {
 
2645
      calculate_interval_lengths(sql_field->charset,
 
2646
                                 sql_field->interval, &dummy, 
 
2647
                                 &field_length);
 
2648
      sql_field->length= field_length + 
 
2649
                         (sql_field->interval->count - 1);
 
2650
    }
 
2651
    else /* MYSQL_TYPE_ENUM */
 
2652
    {
 
2653
      calculate_interval_lengths(sql_field->charset,
 
2654
                                 sql_field->interval,
 
2655
                                 &field_length, &dummy);
 
2656
      sql_field->length= field_length;
 
2657
    }
 
2658
    set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
 
2659
  }
 
2660
 
 
2661
  sql_field->create_length_to_internal_length();
 
2662
  assert(sql_field->def == 0);
 
2663
  /* Can't go wrong as sql_field->def is not defined */
 
2664
  (void) prepare_blob_field(thd, sql_field);
 
2665
}
 
2666
 
 
2667
 
 
2668
/*
1675
2669
  Create a table
1676
2670
 
1677
2671
  SYNOPSIS
1678
2672
    mysql_create_table_no_lock()
1679
 
    session                     Thread object
 
2673
    thd                 Thread object
1680
2674
    db                  Database
1681
2675
    table_name          Table name
1682
2676
    create_info         Create information (like MAX_ROWS)
1683
2677
    fields              List of fields to create
1684
2678
    keys                List of keys to create
1685
2679
    internal_tmp_table  Set to 1 if this is an internal temporary table
1686
 
                        (From ALTER Table)
1687
 
    select_field_count
 
2680
                        (From ALTER TABLE)
 
2681
    select_field_count  
1688
2682
 
1689
2683
  DESCRIPTION
1690
2684
    If one creates a temporary table, this is automatically opened
1704
2698
    true  error
1705
2699
*/
1706
2700
 
1707
 
bool mysql_create_table_no_lock(Session *session,
 
2701
bool mysql_create_table_no_lock(THD *thd,
1708
2702
                                const char *db, const char *table_name,
1709
2703
                                HA_CREATE_INFO *create_info,
1710
2704
                                Alter_info *alter_info,
1711
2705
                                bool internal_tmp_table,
1712
 
                                uint32_t select_field_count,
1713
 
                                bool lock_open_lock)
 
2706
                                uint select_field_count)
1714
2707
{
1715
2708
  char          path[FN_REFLEN];
1716
 
  uint32_t          path_length;
 
2709
  uint          path_length;
1717
2710
  const char    *alias;
1718
2711
  uint          db_options, key_count;
1719
2712
  KEY           *key_info_buffer;
1726
2719
               MYF(0));
1727
2720
    return(true);
1728
2721
  }
1729
 
  if (check_engine(session, table_name, create_info))
 
2722
  if (check_engine(thd, table_name, create_info))
1730
2723
    return(true);
1731
2724
  db_options= create_info->table_options;
1732
2725
  if (create_info->row_type == ROW_TYPE_DYNAMIC)
1733
2726
    db_options|=HA_OPTION_PACK_RECORD;
1734
2727
  alias= table_case_name(create_info, table_name);
1735
 
  if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
 
2728
  if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
1736
2729
                              create_info->db_type)))
1737
2730
  {
1738
2731
    my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1739
2732
    return(true);
1740
2733
  }
1741
2734
 
1742
 
  set_table_default_charset(session, create_info, (char*) db);
 
2735
  set_table_default_charset(thd, create_info, (char*) db);
1743
2736
 
1744
 
  if (mysql_prepare_create_table(session, create_info, alter_info,
 
2737
  if (mysql_prepare_create_table(thd, create_info, alter_info,
1745
2738
                                 internal_tmp_table,
1746
2739
                                 &db_options, file,
1747
2740
                          &key_info_buffer, &key_count,
1751
2744
      /* Check if table exists */
1752
2745
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1753
2746
  {
1754
 
    path_length= build_tmptable_filename(session, path, sizeof(path));
 
2747
    path_length= build_tmptable_filename(thd, path, sizeof(path));
1755
2748
    create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
1756
2749
  }
1757
 
  else
 
2750
  else  
1758
2751
  {
1759
2752
 #ifdef FN_DEVCHAR
1760
2753
    /* check if the table name contains FN_DEVCHAR when defined */
1764
2757
      return(true);
1765
2758
    }
1766
2759
#endif
1767
 
    path_length= build_table_filename(path, sizeof(path), db, alias, "",
 
2760
    path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
1768
2761
                                      internal_tmp_table ? FN_IS_TMP : 0);
1769
2762
  }
1770
2763
 
1771
2764
  /* Check if table already exists */
1772
2765
  if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1773
 
      find_temporary_table(session, db, table_name))
 
2766
      find_temporary_table(thd, db, table_name))
1774
2767
  {
1775
2768
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1776
2769
    {
1777
2770
      create_info->table_existed= 1;            // Mark that table existed
1778
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2771
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1779
2772
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1780
2773
                          alias);
1781
2774
      error= 0;
1785
2778
    goto err;
1786
2779
  }
1787
2780
 
1788
 
  if (lock_open_lock)
1789
 
    pthread_mutex_lock(&LOCK_open);
 
2781
  VOID(pthread_mutex_lock(&LOCK_open));
1790
2782
  if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1791
2783
  {
1792
 
    if (table_proto_exists(path)==EEXIST)
 
2784
    if (!access(path,F_OK))
1793
2785
    {
1794
2786
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1795
2787
        goto warn;
1824
2816
  {
1825
2817
    bool create_if_not_exists =
1826
2818
      create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
1827
 
    int retcode = ha_table_exists_in_engine(session, db, table_name);
 
2819
    int retcode = ha_table_exists_in_engine(thd, db, table_name);
1828
2820
    switch (retcode)
1829
2821
    {
1830
2822
      case HA_ERR_NO_SUCH_TABLE:
1832
2824
        break;
1833
2825
      case HA_ERR_TABLE_EXIST:
1834
2826
 
1835
 
        if (create_if_not_exists)
1836
 
          goto warn;
1837
 
        my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
1838
 
        goto unlock_and_end;
 
2827
      if (create_if_not_exists)
 
2828
        goto warn;
 
2829
      my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
 
2830
      goto unlock_and_end;
 
2831
        break;
1839
2832
      default:
1840
2833
        my_error(retcode, MYF(0),table_name);
1841
2834
        goto unlock_and_end;
1842
2835
    }
1843
2836
  }
1844
2837
 
1845
 
  session->set_proc_info("creating table");
 
2838
  thd_proc_info(thd, "creating table");
1846
2839
  create_info->table_existed= 0;                // Mark that table is created
1847
2840
 
1848
2841
#ifdef HAVE_READLINK
1861
2854
#endif /* HAVE_READLINK */
1862
2855
  {
1863
2856
    if (create_info->data_file_name)
1864
 
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
2857
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
1865
2858
                   "DATA DIRECTORY option ignored");
1866
2859
    if (create_info->index_file_name)
1867
 
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
 
2860
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
1868
2861
                   "INDEX DIRECTORY option ignored");
1869
2862
    create_info->data_file_name= create_info->index_file_name= 0;
1870
2863
  }
1871
2864
  create_info->table_options=db_options;
1872
2865
 
1873
 
  if (rea_create_table(session, path, db, table_name,
 
2866
  path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
 
2867
  if (rea_create_table(thd, path, db, table_name,
1874
2868
                       create_info, alter_info->create_list,
1875
 
                       key_count, key_info_buffer, file, false))
 
2869
                       key_count, key_info_buffer, file))
1876
2870
    goto unlock_and_end;
1877
2871
 
1878
2872
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1879
2873
  {
1880
2874
    /* Open table and put in temporary table list */
1881
 
    if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
 
2875
    if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
1882
2876
    {
1883
 
      (void) rm_temporary_table(create_info->db_type, path);
 
2877
      (void) rm_temporary_table(create_info->db_type, path, false);
1884
2878
      goto unlock_and_end;
1885
2879
    }
1886
 
    session->thread_specific_used= true;
 
2880
    thd->thread_specific_used= true;
1887
2881
  }
1888
2882
 
1889
2883
  /*
1894
2888
    Otherwise, the statement shall be binlogged.
1895
2889
   */
1896
2890
  if (!internal_tmp_table &&
1897
 
      ((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1898
 
    write_bin_log(session, true, session->query, session->query_length);
 
2891
      (!thd->current_stmt_binlog_row_based ||
 
2892
       (thd->current_stmt_binlog_row_based &&
 
2893
        !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
 
2894
    write_bin_log(thd, true, thd->query, thd->query_length);
1899
2895
  error= false;
1900
2896
unlock_and_end:
1901
 
  if (lock_open_lock)
1902
 
    pthread_mutex_unlock(&LOCK_open);
 
2897
  VOID(pthread_mutex_unlock(&LOCK_open));
1903
2898
 
1904
2899
err:
1905
 
  session->set_proc_info("After create");
 
2900
  thd_proc_info(thd, "After create");
1906
2901
  delete file;
1907
2902
  return(error);
1908
2903
 
1909
2904
warn:
1910
2905
  error= false;
1911
 
  push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2906
  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1912
2907
                      ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1913
2908
                      alias);
1914
2909
  create_info->table_existed= 1;                // Mark that table existed
1920
2915
  Database locking aware wrapper for mysql_create_table_no_lock(),
1921
2916
*/
1922
2917
 
1923
 
bool mysql_create_table(Session *session, const char *db, const char *table_name,
 
2918
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
1924
2919
                        HA_CREATE_INFO *create_info,
1925
2920
                        Alter_info *alter_info,
1926
2921
                        bool internal_tmp_table,
1927
 
                        uint32_t select_field_count)
 
2922
                        uint select_field_count)
1928
2923
{
1929
 
  Table *name_lock= 0;
 
2924
  TABLE *name_lock= 0;
1930
2925
  bool result;
1931
2926
 
1932
2927
  /* Wait for any database locks */
1933
2928
  pthread_mutex_lock(&LOCK_lock_db);
1934
 
  while (!session->killed &&
1935
 
         hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
 
2929
  while (!thd->killed &&
 
2930
         hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
1936
2931
  {
1937
 
    wait_for_condition(session, &LOCK_lock_db, &COND_refresh);
 
2932
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1938
2933
    pthread_mutex_lock(&LOCK_lock_db);
1939
2934
  }
1940
2935
 
1941
 
  if (session->killed)
 
2936
  if (thd->killed)
1942
2937
  {
1943
2938
    pthread_mutex_unlock(&LOCK_lock_db);
1944
2939
    return(true);
1948
2943
 
1949
2944
  if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1950
2945
  {
1951
 
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
 
2946
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
1952
2947
    {
1953
2948
      result= true;
1954
2949
      goto unlock;
1957
2952
    {
1958
2953
      if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1959
2954
      {
1960
 
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
2955
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1961
2956
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1962
2957
                            table_name);
1963
2958
        create_info->table_existed= 1;
1972
2967
    }
1973
2968
  }
1974
2969
 
1975
 
  result= mysql_create_table_no_lock(session, db, table_name, create_info,
 
2970
  result= mysql_create_table_no_lock(thd, db, table_name, create_info,
1976
2971
                                     alter_info,
1977
2972
                                     internal_tmp_table,
1978
 
                                     select_field_count, true);
 
2973
                                     select_field_count);
1979
2974
 
1980
2975
unlock:
1981
2976
  if (name_lock)
1982
2977
  {
1983
2978
    pthread_mutex_lock(&LOCK_open);
1984
 
    unlink_open_table(session, name_lock, false);
 
2979
    unlink_open_table(thd, name_lock, false);
1985
2980
    pthread_mutex_unlock(&LOCK_open);
1986
2981
  }
1987
2982
  pthread_mutex_lock(&LOCK_lock_db);
2012
3007
  char buff[MAX_FIELD_NAME],*buff_end;
2013
3008
 
2014
3009
  if (!check_if_keyname_exists(field_name,start,end) &&
2015
 
      !is_primary_key_name(field_name))
 
3010
      my_strcasecmp(system_charset_info,field_name,primary_key_name))
2016
3011
    return (char*) field_name;                  // Use fieldname
2017
 
 
2018
 
  buff_end= strncpy(buff, field_name, sizeof(buff)-4);
2019
 
  buff_end+= strlen(buff);
 
3012
  buff_end=strmake(buff,field_name, sizeof(buff)-4);
2020
3013
 
2021
3014
  /*
2022
3015
    Only 3 chars + '\0' left, so need to limit to 2 digit
2023
3016
    This is ok as we can't have more than 100 keys anyway
2024
3017
  */
2025
 
  for (uint32_t i=2 ; i< 100; i++)
 
3018
  for (uint i=2 ; i< 100; i++)
2026
3019
  {
2027
3020
    *buff_end= '_';
2028
3021
    int10_to_str(i, buff_end+1, 10);
2043
3036
 
2044
3037
  SYNOPSIS
2045
3038
    mysql_rename_table()
2046
 
      base                      The StorageEngine handle.
 
3039
      base                      The handlerton handle.
2047
3040
      old_db                    The old database name.
2048
3041
      old_name                  The old table name.
2049
3042
      new_db                    The new database name.
2060
3053
*/
2061
3054
 
2062
3055
bool
2063
 
mysql_rename_table(StorageEngine *base, const char *old_db,
 
3056
mysql_rename_table(handlerton *base, const char *old_db,
2064
3057
                   const char *old_name, const char *new_db,
2065
 
                   const char *new_name, uint32_t flags)
 
3058
                   const char *new_name, uint flags)
2066
3059
{
2067
 
  Session *session= current_session;
 
3060
  THD *thd= current_thd;
2068
3061
  char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
2069
3062
  char *from_base= from, *to_base= to;
2070
3063
  char tmp_name[NAME_LEN+1];
2072
3065
  int error=0;
2073
3066
 
2074
3067
  file= (base == NULL ? 0 :
2075
 
         get_new_handler((TABLE_SHARE*) 0, session->mem_root, base));
 
3068
         get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
2076
3069
 
2077
3070
  build_table_filename(from, sizeof(from), old_db, old_name, "",
2078
3071
                       flags & FN_FROM_IS_TMP);
2087
3080
  if (lower_case_table_names == 2 && file &&
2088
3081
      !(file->ha_table_flags() & HA_FILE_BASED))
2089
3082
  {
2090
 
    strcpy(tmp_name, old_name);
 
3083
    strmov(tmp_name, old_name);
2091
3084
    my_casedn_str(files_charset_info, tmp_name);
2092
3085
    build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2093
3086
                         flags & FN_FROM_IS_TMP);
2094
3087
    from_base= lc_from;
2095
3088
 
2096
 
    strcpy(tmp_name, new_name);
 
3089
    strmov(tmp_name, new_name);
2097
3090
    my_casedn_str(files_charset_info, tmp_name);
2098
3091
    build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2099
3092
                         flags & FN_TO_IS_TMP);
2101
3094
  }
2102
3095
  if (!file || !(error=file->ha_rename_table(from_base, to_base)))
2103
3096
  {
2104
 
    if(!(flags & NO_FRM_RENAME)
2105
 
       && rename_table_proto_file(from_base, to_base))
 
3097
    if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
2106
3098
    {
2107
 
      error= my_errno;
 
3099
      error=my_errno;
 
3100
      /* Restore old file name */
2108
3101
      if (file)
2109
3102
        file->ha_rename_table(to_base, from_base);
2110
3103
    }
2111
3104
  }
2112
3105
  delete file;
2113
3106
  if (error == HA_ERR_WRONG_COMMAND)
2114
 
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
 
3107
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
2115
3108
  else if (error)
2116
3109
    my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
2117
3110
  return(error != 0);
2123
3116
 
2124
3117
  SYNOPSIS
2125
3118
    wait_while_table_is_used()
2126
 
    session                     Thread handler
 
3119
    thd                 Thread handler
2127
3120
    table               Table to remove from cache
2128
3121
    function            HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2129
3122
                        HA_EXTRA_FORCE_REOPEN if table is not be used
2137
3130
    Win32 clients must also have a WRITE LOCK on the table !
2138
3131
*/
2139
3132
 
2140
 
void wait_while_table_is_used(Session *session, Table *table,
 
3133
void wait_while_table_is_used(THD *thd, TABLE *table,
2141
3134
                              enum ha_extra_function function)
2142
3135
{
2143
3136
 
2144
3137
  safe_mutex_assert_owner(&LOCK_open);
2145
3138
 
2146
 
  table->file->extra(function);
 
3139
  VOID(table->file->extra(function));
2147
3140
  /* Mark all tables that are in use as 'old' */
2148
 
  mysql_lock_abort(session, table, true);       /* end threads waiting on lock */
 
3141
  mysql_lock_abort(thd, table, true);   /* end threads waiting on lock */
2149
3142
 
2150
3143
  /* Wait until all there are no other threads that has this table open */
2151
 
  remove_table_from_cache(session, table->s->db.str,
 
3144
  remove_table_from_cache(thd, table->s->db.str,
2152
3145
                          table->s->table_name.str,
2153
3146
                          RTFC_WAIT_OTHER_THREAD_FLAG);
2154
3147
  return;
2159
3152
 
2160
3153
  SYNOPSIS
2161
3154
    close_cached_table()
2162
 
    session                     Thread handler
 
3155
    thd                 Thread handler
2163
3156
    table               Table to remove from cache
2164
3157
 
2165
3158
  NOTES
2171
3164
    Win32 clients must also have a WRITE LOCK on the table !
2172
3165
*/
2173
3166
 
2174
 
void close_cached_table(Session *session, Table *table)
 
3167
void close_cached_table(THD *thd, TABLE *table)
2175
3168
{
2176
3169
 
2177
 
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
3170
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
2178
3171
  /* Close lock if this is not got with LOCK TABLES */
2179
 
  if (session->lock)
 
3172
  if (thd->lock)
2180
3173
  {
2181
 
    mysql_unlock_tables(session, session->lock);
2182
 
    session->lock=0;                    // Start locked threads
 
3174
    mysql_unlock_tables(thd, thd->lock);
 
3175
    thd->lock=0;                        // Start locked threads
2183
3176
  }
2184
3177
  /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
2185
 
  unlink_open_table(session, table, true);
 
3178
  unlink_open_table(thd, table, true);
2186
3179
 
2187
3180
  /* When lock on LOCK_open is freed other threads can continue */
2188
3181
  broadcast_refresh();
2189
3182
  return;
2190
3183
}
2191
3184
 
2192
 
static int send_check_errmsg(Session *session, TableList* table,
 
3185
static int send_check_errmsg(THD *thd, TABLE_LIST* table,
2193
3186
                             const char* operator_name, const char* errmsg)
2194
3187
 
2195
3188
{
2196
 
  Protocol *protocol= session->protocol;
2197
 
  protocol->prepareForResend();
 
3189
  Protocol *protocol= thd->protocol;
 
3190
  protocol->prepare_for_resend();
2198
3191
  protocol->store(table->alias, system_charset_info);
2199
3192
  protocol->store((char*) operator_name, system_charset_info);
2200
3193
  protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2201
3194
  protocol->store(errmsg, system_charset_info);
2202
 
  session->clear_error();
 
3195
  thd->clear_error();
2203
3196
  if (protocol->write())
2204
3197
    return -1;
2205
3198
  return 1;
2206
3199
}
2207
3200
 
2208
3201
 
2209
 
static int prepare_for_repair(Session *session, TableList *table_list,
 
3202
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
2210
3203
                              HA_CHECK_OPT *check_opt)
2211
3204
{
2212
3205
  int error= 0;
2213
 
  Table tmp_table, *table;
 
3206
  TABLE tmp_table, *table;
2214
3207
  TABLE_SHARE *share;
2215
3208
  char from[FN_REFLEN],tmp[FN_REFLEN+32];
2216
3209
  const char **ext;
2217
3210
  struct stat stat_info;
2218
3211
 
2219
 
  if (!(check_opt->use_frm))
 
3212
  if (!(check_opt->sql_flags & TT_USEFRM))
2220
3213
    return(0);
2221
3214
 
2222
3215
  if (!(table= table_list->table))              /* if open_ltable failed */
2223
3216
  {
2224
3217
    char key[MAX_DBKEY_LENGTH];
2225
 
    uint32_t key_length;
 
3218
    uint key_length;
2226
3219
 
2227
 
    key_length= create_table_def_key(session, key, table_list, 0);
 
3220
    key_length= create_table_def_key(thd, key, table_list, 0);
2228
3221
    pthread_mutex_lock(&LOCK_open);
2229
 
    if (!(share= (get_table_share(session, table_list, key, key_length, 0,
 
3222
    if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
2230
3223
                                  &error))))
2231
3224
    {
2232
3225
      pthread_mutex_unlock(&LOCK_open);
2233
3226
      return(0);                                // Can't open frm file
2234
3227
    }
2235
3228
 
2236
 
    if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
 
3229
    if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2237
3230
    {
2238
3231
      release_table_share(share, RELEASE_NORMAL);
2239
3232
      pthread_mutex_unlock(&LOCK_open);
2244
3237
  }
2245
3238
 
2246
3239
  /*
2247
 
    REPAIR Table ... USE_FRM for temporary tables makes little sense.
 
3240
    REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
2248
3241
  */
2249
3242
  if (table->s->tmp_table)
2250
3243
  {
2251
 
    error= send_check_errmsg(session, table_list, "repair",
 
3244
    error= send_check_errmsg(thd, table_list, "repair",
2252
3245
                             "Cannot repair temporary table from .frm file");
2253
3246
    goto end;
2254
3247
  }
2267
3260
    Check if this is a table type that stores index and data separately,
2268
3261
    like ISAM or MyISAM. We assume fixed order of engine file name
2269
3262
    extentions array. First element of engine file name extentions array
2270
 
    is meta/index file extention. Second element - data file extention.
 
3263
    is meta/index file extention. Second element - data file extention. 
2271
3264
  */
2272
3265
  ext= table->file->bas_ext();
2273
3266
  if (!ext[0] || !ext[1])
2274
3267
    goto end;                                   // No data file
2275
3268
 
2276
3269
  // Name of data file
2277
 
  sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
 
3270
  strxmov(from, table->s->normalized_path.str, ext[1], NullS);
2278
3271
  if (stat(from, &stat_info))
2279
3272
    goto end;                           // Can't use USE_FRM flag
2280
3273
 
2281
 
  snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
2282
 
           from, (unsigned long)current_pid, session->thread_id);
 
3274
  snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
 
3275
           from, current_pid, thd->thread_id);
2283
3276
 
2284
3277
  /* If we could open the table, close it */
2285
3278
  if (table_list->table)
2286
3279
  {
2287
3280
    pthread_mutex_lock(&LOCK_open);
2288
 
    close_cached_table(session, table);
 
3281
    close_cached_table(thd, table);
2289
3282
    pthread_mutex_unlock(&LOCK_open);
2290
3283
  }
2291
 
  if (lock_and_wait_for_table_name(session,table_list))
 
3284
  if (lock_and_wait_for_table_name(thd,table_list))
2292
3285
  {
2293
3286
    error= -1;
2294
3287
    goto end;
2296
3289
  if (my_rename(from, tmp, MYF(MY_WME)))
2297
3290
  {
2298
3291
    pthread_mutex_lock(&LOCK_open);
2299
 
    unlock_table_name(session, table_list);
 
3292
    unlock_table_name(thd, table_list);
2300
3293
    pthread_mutex_unlock(&LOCK_open);
2301
 
    error= send_check_errmsg(session, table_list, "repair",
 
3294
    error= send_check_errmsg(thd, table_list, "repair",
2302
3295
                             "Failed renaming data file");
2303
3296
    goto end;
2304
3297
  }
2305
 
  if (mysql_truncate(session, table_list, 1))
 
3298
  if (mysql_truncate(thd, table_list, 1))
2306
3299
  {
2307
3300
    pthread_mutex_lock(&LOCK_open);
2308
 
    unlock_table_name(session, table_list);
 
3301
    unlock_table_name(thd, table_list);
2309
3302
    pthread_mutex_unlock(&LOCK_open);
2310
 
    error= send_check_errmsg(session, table_list, "repair",
 
3303
    error= send_check_errmsg(thd, table_list, "repair",
2311
3304
                             "Failed generating table from .frm file");
2312
3305
    goto end;
2313
3306
  }
2314
3307
  if (my_rename(tmp, from, MYF(MY_WME)))
2315
3308
  {
2316
3309
    pthread_mutex_lock(&LOCK_open);
2317
 
    unlock_table_name(session, table_list);
 
3310
    unlock_table_name(thd, table_list);
2318
3311
    pthread_mutex_unlock(&LOCK_open);
2319
 
    error= send_check_errmsg(session, table_list, "repair",
 
3312
    error= send_check_errmsg(thd, table_list, "repair",
2320
3313
                             "Failed restoring .MYD file");
2321
3314
    goto end;
2322
3315
  }
2326
3319
    to finish the repair in the handler later on.
2327
3320
  */
2328
3321
  pthread_mutex_lock(&LOCK_open);
2329
 
  if (reopen_name_locked_table(session, table_list, true))
 
3322
  if (reopen_name_locked_table(thd, table_list, true))
2330
3323
  {
2331
 
    unlock_table_name(session, table_list);
 
3324
    unlock_table_name(thd, table_list);
2332
3325
    pthread_mutex_unlock(&LOCK_open);
2333
 
    error= send_check_errmsg(session, table_list, "repair",
 
3326
    error= send_check_errmsg(thd, table_list, "repair",
2334
3327
                             "Failed to open partially repaired table");
2335
3328
    goto end;
2336
3329
  }
2340
3333
  if (table == &tmp_table)
2341
3334
  {
2342
3335
    pthread_mutex_lock(&LOCK_open);
2343
 
    table->closefrm(true);                              // Free allocated memory
 
3336
    closefrm(table, 1);                         // Free allocated memory
2344
3337
    pthread_mutex_unlock(&LOCK_open);
2345
3338
  }
2346
3339
  return(error);
2351
3344
/*
2352
3345
  RETURN VALUES
2353
3346
    false Message sent to net (admin operation went ok)
2354
 
    true  Message should be sent by caller
 
3347
    true  Message should be sent by caller 
2355
3348
          (admin operation or network communication failed)
2356
3349
*/
2357
 
static bool mysql_admin_table(Session* session, TableList* tables,
 
3350
static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
2358
3351
                              HA_CHECK_OPT* check_opt,
2359
3352
                              const char *operator_name,
2360
3353
                              thr_lock_type lock_type,
2361
3354
                              bool open_for_modify,
2362
3355
                              bool no_warnings_for_error,
2363
 
                              uint32_t extra_open_options,
2364
 
                              int (*prepare_func)(Session *, TableList *,
 
3356
                              uint extra_open_options,
 
3357
                              int (*prepare_func)(THD *, TABLE_LIST *,
2365
3358
                                                  HA_CHECK_OPT *),
2366
 
                              int (handler::*operator_func)(Session *,
 
3359
                              int (handler::*operator_func)(THD *,
2367
3360
                                                            HA_CHECK_OPT *))
2368
3361
{
2369
 
  TableList *table;
2370
 
  Select_Lex *select= &session->lex->select_lex;
 
3362
  TABLE_LIST *table;
 
3363
  SELECT_LEX *select= &thd->lex->select_lex;
2371
3364
  List<Item> field_list;
2372
3365
  Item *item;
2373
 
  Protocol *protocol= session->protocol;
2374
 
  LEX *lex= session->lex;
 
3366
  Protocol *protocol= thd->protocol;
 
3367
  LEX *lex= thd->lex;
2375
3368
  int result_code= 0;
2376
 
  const CHARSET_INFO * const cs= system_charset_info;
 
3369
  CHARSET_INFO *cs= system_charset_info;
2377
3370
 
2378
 
  if (! session->endActiveTransaction())
 
3371
  if (end_active_trans(thd))
2379
3372
    return(1);
2380
3373
  field_list.push_back(item = new Item_empty_string("Table",
2381
3374
                                                    NAME_CHAR_LEN * 2,
2387
3380
  item->maybe_null = 1;
2388
3381
  field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
2389
3382
  item->maybe_null = 1;
2390
 
  if (protocol->sendFields(&field_list,
2391
 
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
3383
  if (protocol->send_fields(&field_list,
 
3384
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2392
3385
    return(true);
2393
3386
 
 
3387
  mysql_ha_rm_tables(thd, tables, false);
 
3388
 
2394
3389
  for (table= tables; table; table= table->next_local)
2395
3390
  {
2396
3391
    char table_name[NAME_LEN*2+2];
2397
3392
    char* db = table->db;
2398
3393
    bool fatal_error=0;
2399
3394
 
2400
 
    sprintf(table_name,"%s.%s",db,table->table_name);
2401
 
    session->open_options|= extra_open_options;
 
3395
    strxmov(table_name, db, ".", table->table_name, NullS);
 
3396
    thd->open_options|= extra_open_options;
2402
3397
    table->lock_type= lock_type;
2403
3398
    /* open only one table from local list of command */
2404
3399
    {
2405
 
      TableList *save_next_global, *save_next_local;
 
3400
      TABLE_LIST *save_next_global, *save_next_local;
2406
3401
      save_next_global= table->next_global;
2407
3402
      table->next_global= 0;
2408
3403
      save_next_local= table->next_local;
2409
3404
      table->next_local= 0;
2410
 
      select->table_list.first= (unsigned char*)table;
 
3405
      select->table_list.first= (uchar*)table;
2411
3406
      /*
2412
3407
        Time zone tables and SP tables can be add to lex->query_tables list,
2413
3408
        so it have to be prepared.
2417
3412
      lex->query_tables= table;
2418
3413
      lex->query_tables_last= &table->next_global;
2419
3414
      lex->query_tables_own_last= 0;
2420
 
      session->no_warnings_for_error= no_warnings_for_error;
 
3415
      thd->no_warnings_for_error= no_warnings_for_error;
 
3416
      table->required_type=FRMTYPE_TABLE;
2421
3417
 
2422
 
      open_and_lock_tables(session, table);
2423
 
      session->no_warnings_for_error= 0;
 
3418
      open_and_lock_tables(thd, table);
 
3419
      thd->no_warnings_for_error= 0;
2424
3420
      table->next_global= save_next_global;
2425
3421
      table->next_local= save_next_local;
2426
 
      session->open_options&= ~extra_open_options;
 
3422
      thd->open_options&= ~extra_open_options;
2427
3423
    }
2428
3424
 
2429
3425
    if (prepare_func)
2430
3426
    {
2431
 
      switch ((*prepare_func)(session, table, check_opt)) {
 
3427
      switch ((*prepare_func)(thd, table, check_opt)) {
2432
3428
      case  1:           // error, message written to net
2433
 
        ha_autocommit_or_rollback(session, 1);
2434
 
        session->endTransaction(ROLLBACK);
2435
 
        close_thread_tables(session);
 
3429
        ha_autocommit_or_rollback(thd, 1);
 
3430
        end_trans(thd, ROLLBACK);
 
3431
        close_thread_tables(thd);
2436
3432
        continue;
2437
3433
      case -1:           // error, message could be written to net
2438
3434
        /* purecov: begin inspected */
2444
3440
    }
2445
3441
 
2446
3442
    /*
2447
 
      CHECK Table command is only command where VIEW allowed here and this
 
3443
      CHECK TABLE command is only command where VIEW allowed here and this
2448
3444
      command use only temporary teble method for VIEWs resolving => there
2449
3445
      can't be VIEW tree substitition of join view => if opening table
2450
 
      succeed then table->table will have real Table pointer as value (in
 
3446
      succeed then table->table will have real TABLE pointer as value (in
2451
3447
      case of join view substitution table->table can be 0, but here it is
2452
3448
      impossible)
2453
3449
    */
2454
3450
    if (!table->table)
2455
3451
    {
2456
 
      if (!session->warn_list.elements)
2457
 
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
3452
      if (!thd->warn_list.elements)
 
3453
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
2458
3454
                     ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
2459
3455
      goto send_result;
2460
3456
    }
2462
3458
    if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
2463
3459
    {
2464
3460
      /* purecov: begin inspected */
2465
 
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
2466
 
      uint32_t length;
2467
 
      protocol->prepareForResend();
 
3461
      char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
 
3462
      uint length;
 
3463
      protocol->prepare_for_resend();
2468
3464
      protocol->store(table_name, system_charset_info);
2469
3465
      protocol->store(operator_name, system_charset_info);
2470
3466
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2471
3467
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2472
3468
                       table_name);
2473
3469
      protocol->store(buff, length, system_charset_info);
2474
 
      ha_autocommit_or_rollback(session, 0);
2475
 
      session->endTransaction(COMMIT);
2476
 
      close_thread_tables(session);
 
3470
      ha_autocommit_or_rollback(thd, 0);
 
3471
      end_trans(thd, COMMIT);
 
3472
      close_thread_tables(thd);
2477
3473
      lex->reset_query_tables_list(false);
2478
3474
      table->table=0;                           // For query cache
2479
3475
      if (protocol->write())
2486
3482
    if (lock_type == TL_WRITE && table->table->s->version)
2487
3483
    {
2488
3484
      pthread_mutex_lock(&LOCK_open);
2489
 
      const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
 
3485
      const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
2490
3486
                                              "Waiting to get writelock");
2491
 
      mysql_lock_abort(session,table->table, true);
2492
 
      remove_table_from_cache(session, table->table->s->db.str,
 
3487
      mysql_lock_abort(thd,table->table, true);
 
3488
      remove_table_from_cache(thd, table->table->s->db.str,
2493
3489
                              table->table->s->table_name.str,
2494
3490
                              RTFC_WAIT_OTHER_THREAD_FLAG |
2495
3491
                              RTFC_CHECK_KILLED_FLAG);
2496
 
      session->exit_cond(old_message);
2497
 
      if (session->killed)
 
3492
      thd->exit_cond(old_message);
 
3493
      if (thd->killed)
2498
3494
        goto err;
2499
3495
      open_for_modify= 0;
2500
3496
    }
2502
3498
    if (table->table->s->crashed && operator_func == &handler::ha_check)
2503
3499
    {
2504
3500
      /* purecov: begin inspected */
2505
 
      protocol->prepareForResend();
 
3501
      protocol->prepare_for_resend();
2506
3502
      protocol->store(table_name, system_charset_info);
2507
3503
      protocol->store(operator_name, system_charset_info);
2508
3504
      protocol->store(STRING_WITH_LEN("warning"), system_charset_info);
2513
3509
      /* purecov: end */
2514
3510
    }
2515
3511
 
2516
 
    if (operator_func == &handler::ha_repair && !(check_opt->use_frm))
 
3512
    if (operator_func == &handler::ha_repair &&
 
3513
        !(check_opt->sql_flags & TT_USEFRM))
2517
3514
    {
2518
3515
      if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
2519
3516
          (table->table->file->ha_check_for_upgrade(check_opt) ==
2520
3517
           HA_ADMIN_NEEDS_ALTER))
2521
3518
      {
2522
 
        ha_autocommit_or_rollback(session, 1);
2523
 
        close_thread_tables(session);
2524
 
        result_code= mysql_recreate_table(session, table);
 
3519
        ha_autocommit_or_rollback(thd, 1);
 
3520
        close_thread_tables(thd);
 
3521
        tmp_disable_binlog(thd); // binlogging is done by caller if wanted
 
3522
        result_code= mysql_recreate_table(thd, table);
 
3523
        reenable_binlog(thd);
2525
3524
        /*
2526
3525
          mysql_recreate_table() can push OK or ERROR.
2527
3526
          Clear 'OK' status. If there is an error, keep it:
2528
 
          we will store the error message in a result set row
 
3527
          we will store the error message in a result set row 
2529
3528
          and then clear.
2530
3529
        */
2531
 
        if (session->main_da.is_ok())
2532
 
          session->main_da.reset_diagnostics_area();
 
3530
        if (thd->main_da.is_ok())
 
3531
          thd->main_da.reset_diagnostics_area();
2533
3532
        goto send_result;
2534
3533
      }
2535
3534
    }
2536
3535
 
2537
 
    result_code = (table->table->file->*operator_func)(session, check_opt);
 
3536
    result_code = (table->table->file->*operator_func)(thd, check_opt);
2538
3537
 
2539
3538
send_result:
2540
3539
 
2541
3540
    lex->cleanup_after_one_table_open();
2542
 
    session->clear_error();  // these errors shouldn't get client
 
3541
    thd->clear_error();  // these errors shouldn't get client
2543
3542
    {
2544
 
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2545
 
      DRIZZLE_ERROR *err;
 
3543
      List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
 
3544
      MYSQL_ERROR *err;
2546
3545
      while ((err= it++))
2547
3546
      {
2548
 
        protocol->prepareForResend();
 
3547
        protocol->prepare_for_resend();
2549
3548
        protocol->store(table_name, system_charset_info);
2550
3549
        protocol->store((char*) operator_name, system_charset_info);
2551
3550
        protocol->store(warning_level_names[err->level].str,
2555
3554
        if (protocol->write())
2556
3555
          goto err;
2557
3556
      }
2558
 
      drizzle_reset_errors(session, true);
 
3557
      mysql_reset_errors(thd, true);
2559
3558
    }
2560
 
    protocol->prepareForResend();
 
3559
    protocol->prepare_for_resend();
2561
3560
    protocol->store(table_name, system_charset_info);
2562
3561
    protocol->store(operator_name, system_charset_info);
2563
3562
 
2567
3566
    case HA_ADMIN_NOT_IMPLEMENTED:
2568
3567
      {
2569
3568
        char buf[ERRMSGSIZE+20];
2570
 
        uint32_t length=snprintf(buf, ERRMSGSIZE,
 
3569
        uint length=snprintf(buf, ERRMSGSIZE,
2571
3570
                             ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
2572
3571
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
2573
3572
        protocol->store(buf, length, system_charset_info);
2574
3573
      }
2575
3574
      break;
2576
3575
 
 
3576
    case HA_ADMIN_NOT_BASE_TABLE:
 
3577
      {
 
3578
        char buf[ERRMSGSIZE+20];
 
3579
        uint length= snprintf(buf, ERRMSGSIZE,
 
3580
                              ER(ER_BAD_TABLE_ERROR), table_name);
 
3581
        protocol->store(STRING_WITH_LEN("note"), system_charset_info);
 
3582
        protocol->store(buf, length, system_charset_info);
 
3583
      }
 
3584
      break;
 
3585
 
2577
3586
    case HA_ADMIN_OK:
2578
3587
      protocol->store(STRING_WITH_LEN("status"), system_charset_info);
2579
3588
      protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
2614
3623
    {
2615
3624
      /*
2616
3625
        This is currently used only by InnoDB. ha_innobase::optimize() answers
2617
 
        "try with alter", so here we close the table, do an ALTER Table,
 
3626
        "try with alter", so here we close the table, do an ALTER TABLE,
2618
3627
        reopen the table and do ha_innobase::analyze() on it.
2619
3628
      */
2620
 
      ha_autocommit_or_rollback(session, 0);
2621
 
      close_thread_tables(session);
2622
 
      TableList *save_next_local= table->next_local,
 
3629
      ha_autocommit_or_rollback(thd, 0);
 
3630
      close_thread_tables(thd);
 
3631
      TABLE_LIST *save_next_local= table->next_local,
2623
3632
                 *save_next_global= table->next_global;
2624
3633
      table->next_local= table->next_global= 0;
2625
 
      result_code= mysql_recreate_table(session, table);
 
3634
      tmp_disable_binlog(thd); // binlogging is done by caller if wanted
 
3635
      result_code= mysql_recreate_table(thd, table);
 
3636
      reenable_binlog(thd);
2626
3637
      /*
2627
3638
        mysql_recreate_table() can push OK or ERROR.
2628
3639
        Clear 'OK' status. If there is an error, keep it:
2629
 
        we will store the error message in a result set row
 
3640
        we will store the error message in a result set row 
2630
3641
        and then clear.
2631
3642
      */
2632
 
      if (session->main_da.is_ok())
2633
 
        session->main_da.reset_diagnostics_area();
2634
 
      ha_autocommit_or_rollback(session, 0);
2635
 
      close_thread_tables(session);
 
3643
      if (thd->main_da.is_ok())
 
3644
        thd->main_da.reset_diagnostics_area();
 
3645
      ha_autocommit_or_rollback(thd, 0);
 
3646
      close_thread_tables(thd);
2636
3647
      if (!result_code) // recreation went ok
2637
3648
      {
2638
 
        if ((table->table= open_ltable(session, table, lock_type, 0)) &&
2639
 
            ((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
 
3649
        if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
 
3650
            ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
2640
3651
          result_code= 0; // analyze went ok
2641
3652
      }
2642
3653
      if (result_code) // either mysql_recreate_table or analyze failed
2643
3654
      {
2644
 
        assert(session->is_error());
2645
 
        if (session->is_error())
 
3655
        assert(thd->is_error());
 
3656
        if (thd->is_error())
2646
3657
        {
2647
 
          const char *err_msg= session->main_da.message();
2648
 
          if (!session->protocol->isConnected())
 
3658
          const char *err_msg= thd->main_da.message();
 
3659
          if (!thd->vio_ok())
2649
3660
          {
2650
 
            errmsg_printf(ERRMSG_LVL_ERROR, "%s", err_msg);
 
3661
            sql_print_error(err_msg);
2651
3662
          }
2652
3663
          else
2653
3664
          {
2656
3667
            protocol->store(err_msg, system_charset_info);
2657
3668
            (void)protocol->write();
2658
3669
            /* Start off another row for HA_ADMIN_FAILED */
2659
 
            protocol->prepareForResend();
 
3670
            protocol->prepare_for_resend();
2660
3671
            protocol->store(table_name, system_charset_info);
2661
3672
            protocol->store(operator_name, system_charset_info);
2662
3673
          }
2663
 
          session->clear_error();
 
3674
          thd->clear_error();
2664
3675
        }
2665
3676
      }
2666
3677
      result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
2668
3679
      table->next_global= save_next_global;
2669
3680
      goto send_result_message;
2670
3681
    }
 
3682
    case HA_ADMIN_WRONG_CHECKSUM:
 
3683
    {
 
3684
      protocol->store(STRING_WITH_LEN("note"), system_charset_info);
 
3685
      protocol->store(ER(ER_VIEW_CHECKSUM), strlen(ER(ER_VIEW_CHECKSUM)),
 
3686
                      system_charset_info);
 
3687
      break;
 
3688
    }
 
3689
 
2671
3690
    case HA_ADMIN_NEEDS_UPGRADE:
2672
3691
    case HA_ADMIN_NEEDS_ALTER:
2673
3692
    {
2674
3693
      char buf[ERRMSGSIZE];
2675
 
      uint32_t length;
 
3694
      uint length;
2676
3695
 
2677
3696
      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2678
3697
      length=snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
2684
3703
    default:                            // Probably HA_ADMIN_INTERNAL_ERROR
2685
3704
      {
2686
3705
        char buf[ERRMSGSIZE+20];
2687
 
        uint32_t length=snprintf(buf, ERRMSGSIZE,
2688
 
                             _("Unknown - internal error %d during operation"),
 
3706
        uint length=snprintf(buf, ERRMSGSIZE,
 
3707
                             "Unknown - internal error %d during operation",
2689
3708
                             result_code);
2690
3709
        protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2691
3710
        protocol->store(buf, length, system_charset_info);
2704
3723
        else
2705
3724
        {
2706
3725
          pthread_mutex_lock(&LOCK_open);
2707
 
          remove_table_from_cache(session, table->table->s->db.str,
 
3726
          remove_table_from_cache(thd, table->table->s->db.str,
2708
3727
                                  table->table->s->table_name.str, RTFC_NO_FLAG);
2709
3728
          pthread_mutex_unlock(&LOCK_open);
2710
3729
        }
2711
3730
      }
2712
3731
    }
2713
 
    ha_autocommit_or_rollback(session, 0);
2714
 
    session->endTransaction(COMMIT);
2715
 
    close_thread_tables(session);
 
3732
    ha_autocommit_or_rollback(thd, 0);
 
3733
    end_trans(thd, COMMIT);
 
3734
    close_thread_tables(thd);
2716
3735
    table->table=0;                             // For query cache
2717
3736
    if (protocol->write())
2718
3737
      goto err;
2719
3738
  }
2720
3739
 
2721
 
  session->my_eof();
 
3740
  my_eof(thd);
2722
3741
  return(false);
2723
3742
 
2724
3743
err:
2725
 
  ha_autocommit_or_rollback(session, 1);
2726
 
  session->endTransaction(ROLLBACK);
2727
 
  close_thread_tables(session);                 // Shouldn't be needed
 
3744
  ha_autocommit_or_rollback(thd, 1);
 
3745
  end_trans(thd, ROLLBACK);
 
3746
  close_thread_tables(thd);                     // Shouldn't be needed
2728
3747
  if (table)
2729
3748
    table->table=0;
2730
3749
  return(true);
2731
3750
}
2732
3751
 
2733
3752
 
2734
 
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
 
3753
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
2735
3754
{
2736
 
  return(mysql_admin_table(session, tables, check_opt,
2737
 
                           "repair", TL_WRITE, 1,
2738
 
                           check_opt->use_frm,
2739
 
                           HA_OPEN_FOR_REPAIR,
2740
 
                           &prepare_for_repair,
2741
 
                           &handler::ha_repair));
 
3755
  return(mysql_admin_table(thd, tables, check_opt,
 
3756
                                "repair", TL_WRITE, 1,
 
3757
                                test(check_opt->sql_flags & TT_USEFRM),
 
3758
                                HA_OPEN_FOR_REPAIR,
 
3759
                                &prepare_for_repair,
 
3760
                                &handler::ha_repair));
2742
3761
}
2743
3762
 
2744
3763
 
2745
 
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
 
3764
bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
2746
3765
{
2747
 
  return(mysql_admin_table(session, tables, check_opt,
2748
 
                           "optimize", TL_WRITE, 1,0,0,0,
2749
 
                           &handler::ha_optimize));
 
3766
  return(mysql_admin_table(thd, tables, check_opt,
 
3767
                                "optimize", TL_WRITE, 1,0,0,0,
 
3768
                                &handler::ha_optimize));
2750
3769
}
2751
3770
 
2752
3771
 
2755
3774
 
2756
3775
  SYNOPSIS
2757
3776
    mysql_assign_to_keycache()
2758
 
    session             Thread object
 
3777
    thd         Thread object
2759
3778
    tables      Table list (one table only)
2760
3779
 
2761
3780
  RETURN VALUES
2763
3782
   true  error
2764
3783
*/
2765
3784
 
2766
 
bool mysql_assign_to_keycache(Session* session, TableList* tables,
 
3785
bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
2767
3786
                             LEX_STRING *key_cache_name)
2768
3787
{
2769
3788
  HA_CHECK_OPT check_opt;
2779
3798
  }
2780
3799
  pthread_mutex_unlock(&LOCK_global_system_variables);
2781
3800
  check_opt.key_cache= key_cache;
2782
 
  return(mysql_admin_table(session, tables, &check_opt,
 
3801
  return(mysql_admin_table(thd, tables, &check_opt,
2783
3802
                                "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
2784
3803
                                0, 0, &handler::assign_to_keycache));
2785
3804
}
2790
3809
 
2791
3810
  SYNOPSIS
2792
3811
    reassign_keycache_tables()
2793
 
    session             Thread object
 
3812
    thd         Thread object
2794
3813
    src_cache   Reference to the key cache to clean up
2795
3814
    dest_cache  New key cache
2796
3815
 
2810
3829
    0     ok
2811
3830
*/
2812
3831
 
2813
 
int reassign_keycache_tables(Session *,
 
3832
int reassign_keycache_tables(THD *thd __attribute__((__unused__)),
2814
3833
                             KEY_CACHE *src_cache,
2815
3834
                             KEY_CACHE *dst_cache)
2816
3835
{
2825
3844
/**
2826
3845
  @brief          Create frm file based on I_S table
2827
3846
 
2828
 
  @param[in]      session                      thread handler
2829
 
  @param[in]      schema_table             I_S table
 
3847
  @param[in]      thd                      thread handler
 
3848
  @param[in]      schema_table             I_S table           
2830
3849
  @param[in]      dst_path                 path where frm should be created
2831
3850
  @param[in]      create_info              Create info
2832
3851
 
2834
3853
    @retval       0                        success
2835
3854
    @retval       1                        error
2836
3855
*/
2837
 
bool mysql_create_like_schema_frm(Session* session, TableList* schema_table,
 
3856
bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
2838
3857
                                  char *dst_path, HA_CREATE_INFO *create_info)
2839
3858
{
2840
3859
  HA_CREATE_INFO local_create_info;
2841
3860
  Alter_info alter_info;
2842
3861
  bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
2843
 
  uint32_t keys= schema_table->table->s->keys;
2844
 
  uint32_t db_options= 0;
 
3862
  uint keys= schema_table->table->s->keys;
 
3863
  uint db_options= 0;
2845
3864
 
2846
 
  memset(&local_create_info, 0, sizeof(local_create_info));
 
3865
  bzero((char*) &local_create_info, sizeof(local_create_info));
2847
3866
  local_create_info.db_type= schema_table->table->s->db_type();
2848
3867
  local_create_info.row_type= schema_table->table->s->row_type;
2849
3868
  local_create_info.default_table_charset=default_charset_info;
2850
3869
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2851
3870
  schema_table->table->use_all_columns();
2852
 
  if (mysql_prepare_alter_table(session, schema_table->table,
 
3871
  if (mysql_prepare_alter_table(thd, schema_table->table,
2853
3872
                                &local_create_info, &alter_info))
2854
 
    return true;
2855
 
 
2856
 
  if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
 
3873
    return(1);
 
3874
  if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
2857
3875
                                 tmp_table, &db_options,
2858
3876
                                 schema_table->table->file,
2859
3877
                                 &schema_table->table->s->key_info, &keys, 0))
2860
 
    return true;
2861
 
 
 
3878
    return(1);
2862
3879
  local_create_info.max_rows= 0;
2863
 
  if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
 
3880
  if (mysql_create_frm(thd, dst_path, NullS, NullS,
2864
3881
                       &local_create_info, alter_info.create_list,
2865
3882
                       keys, schema_table->table->s->key_info,
2866
 
                       schema_table->table->file, true))
2867
 
    return true;
2868
 
 
2869
 
  return false;
 
3883
                       schema_table->table->file))
 
3884
    return(1);
 
3885
  return(0);
2870
3886
}
2871
3887
 
 
3888
 
2872
3889
/*
2873
3890
  Create a table identical to the specified table
2874
3891
 
2875
3892
  SYNOPSIS
2876
3893
    mysql_create_like_table()
2877
 
    session             Thread object
 
3894
    thd         Thread object
2878
3895
    table       Table list element for target table
2879
3896
    src_table   Table list element for source table
2880
3897
    create_info Create info
2884
3901
    true  error
2885
3902
*/
2886
3903
 
2887
 
bool mysql_create_like_table(Session* session, TableList* table, TableList* src_table,
 
3904
bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
2888
3905
                             HA_CREATE_INFO *create_info)
2889
3906
{
2890
 
  Table *name_lock= 0;
 
3907
  TABLE *name_lock= 0;
2891
3908
  char src_path[FN_REFLEN], dst_path[FN_REFLEN];
2892
 
  uint32_t dst_path_length;
 
3909
  uint dst_path_length;
2893
3910
  char *db= table->db;
2894
3911
  char *table_name= table->table_name;
2895
3912
  int  err;
2896
3913
  bool res= true;
2897
 
  uint32_t not_used;
 
3914
  uint not_used;
 
3915
 
 
3916
 
 
3917
  /* CREATE TABLE ... LIKE is not allowed for views. */
 
3918
  src_table->required_type= FRMTYPE_TABLE;
2898
3919
 
2899
3920
  /*
2900
3921
    By opening source table we guarantee that it exists and no concurrent
2905
3926
    we ensure that our statement is properly isolated from all concurrent
2906
3927
    operations which matter.
2907
3928
  */
2908
 
  if (open_tables(session, &src_table, &not_used, 0))
 
3929
  if (open_tables(thd, &src_table, &not_used, 0))
2909
3930
    return(true);
2910
3931
 
2911
 
  strncpy(src_path, src_table->table->s->path.str, sizeof(src_path));
 
3932
  strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
2912
3933
 
2913
 
  /*
 
3934
  /* 
2914
3935
    Check that destination tables does not exist. Note that its name
2915
3936
    was already checked when it was added to the table list.
2916
3937
  */
2917
3938
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2918
3939
  {
2919
 
    if (find_temporary_table(session, db, table_name))
 
3940
    if (find_temporary_table(thd, db, table_name))
2920
3941
      goto table_exists;
2921
 
    dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
 
3942
    dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
2922
3943
    create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2923
3944
  }
2924
3945
  else
2925
3946
  {
2926
 
    if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
 
3947
    if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
2927
3948
      goto err;
2928
3949
    if (!name_lock)
2929
3950
      goto table_exists;
2930
3951
    dst_path_length= build_table_filename(dst_path, sizeof(dst_path),
2931
 
                                          db, table_name, "", 0);
2932
 
    if (table_proto_exists(dst_path)==EEXIST)
 
3952
                                          db, table_name, reg_ext, 0);
 
3953
    if (!access(dst_path, F_OK))
2933
3954
      goto table_exists;
2934
3955
  }
2935
3956
 
2946
3967
    Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2947
3968
    during the call to ha_create_table(). See bug #28614 for more info.
2948
3969
  */
2949
 
  pthread_mutex_lock(&LOCK_open);
 
3970
  VOID(pthread_mutex_lock(&LOCK_open));
2950
3971
  if (src_table->schema_table)
2951
3972
  {
2952
 
    if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
 
3973
    if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
2953
3974
    {
2954
 
      pthread_mutex_unlock(&LOCK_open);
 
3975
      VOID(pthread_mutex_unlock(&LOCK_open));
2955
3976
      goto err;
2956
3977
    }
2957
3978
  }
2958
 
  else
 
3979
  else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
2959
3980
  {
2960
 
    int dfecopyr= copy_table_proto_file(src_path, dst_path);
2961
 
 
2962
 
    if(dfecopyr)
2963
 
    {
2964
 
      if (my_errno == ENOENT)
2965
 
        my_error(ER_BAD_DB_ERROR,MYF(0),db);
2966
 
      else
2967
 
        my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2968
 
      pthread_mutex_unlock(&LOCK_open);
2969
 
      goto err;
2970
 
    }
 
3981
    if (my_errno == ENOENT)
 
3982
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
3983
    else
 
3984
      my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
 
3985
    VOID(pthread_mutex_unlock(&LOCK_open));
 
3986
    goto err;
2971
3987
  }
2972
3988
 
2973
3989
  /*
2975
3991
    creation, instead create the table directly (for both normal
2976
3992
    and temporary tables).
2977
3993
  */
2978
 
 
2979
 
  if (session->variables.keep_files_on_create)
 
3994
  dst_path[dst_path_length - reg_ext_length]= '\0';  // Remove .frm
 
3995
  if (thd->variables.keep_files_on_create)
2980
3996
    create_info->options|= HA_CREATE_KEEP_FILES;
2981
 
  err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
2982
 
  pthread_mutex_unlock(&LOCK_open);
 
3997
  err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
 
3998
  VOID(pthread_mutex_unlock(&LOCK_open));
2983
3999
 
2984
4000
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2985
4001
  {
2986
 
    if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
 
4002
    if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
2987
4003
                                     OTM_OPEN))
2988
4004
    {
2989
4005
      (void) rm_temporary_table(create_info->db_type,
2990
 
                                dst_path);
 
4006
                                dst_path, false); /* purecov: inspected */
2991
4007
      goto err;     /* purecov: inspected */
2992
4008
    }
2993
4009
  }
3001
4017
  /*
3002
4018
    We have to write the query before we unlock the tables.
3003
4019
  */
 
4020
  if (thd->current_stmt_binlog_row_based)
3004
4021
  {
3005
4022
    /*
3006
4023
       Since temporary tables are not replicated under row-based
3033
4050
          of this function.
3034
4051
        */
3035
4052
        table->table= name_lock;
3036
 
        pthread_mutex_lock(&LOCK_open);
3037
 
        if (reopen_name_locked_table(session, table, false))
 
4053
        VOID(pthread_mutex_lock(&LOCK_open));
 
4054
        if (reopen_name_locked_table(thd, table, false))
3038
4055
        {
3039
 
          pthread_mutex_unlock(&LOCK_open);
 
4056
          VOID(pthread_mutex_unlock(&LOCK_open));
3040
4057
          goto err;
3041
4058
        }
3042
 
        pthread_mutex_unlock(&LOCK_open);
 
4059
        VOID(pthread_mutex_unlock(&LOCK_open));
3043
4060
 
3044
 
        int result= store_create_info(session, table, &query,
 
4061
        int result= store_create_info(thd, table, &query,
3045
4062
                                               create_info);
3046
4063
 
3047
4064
        assert(result == 0); // store_create_info() always return 0
3048
 
        write_bin_log(session, true, query.ptr(), query.length());
 
4065
        write_bin_log(thd, true, query.ptr(), query.length());
3049
4066
      }
3050
4067
      else                                      // Case 1
3051
 
        write_bin_log(session, true, session->query, session->query_length);
 
4068
        write_bin_log(thd, true, thd->query, thd->query_length);
3052
4069
    }
3053
4070
    /*
3054
4071
      Case 3 and 4 does nothing under RBR
3055
4072
    */
3056
4073
  }
 
4074
  else
 
4075
    write_bin_log(thd, true, thd->query, thd->query_length);
3057
4076
 
3058
4077
  res= false;
3059
4078
  goto err;
3061
4080
table_exists:
3062
4081
  if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
3063
4082
  {
3064
 
    char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
4083
    char warn_buff[MYSQL_ERRMSG_SIZE];
3065
4084
    snprintf(warn_buff, sizeof(warn_buff),
3066
4085
             ER(ER_TABLE_EXISTS_ERROR), table_name);
3067
 
    push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4086
    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3068
4087
                 ER_TABLE_EXISTS_ERROR,warn_buff);
3069
4088
    res= false;
3070
4089
  }
3075
4094
  if (name_lock)
3076
4095
  {
3077
4096
    pthread_mutex_lock(&LOCK_open);
3078
 
    unlink_open_table(session, name_lock, false);
 
4097
    unlink_open_table(thd, name_lock, false);
3079
4098
    pthread_mutex_unlock(&LOCK_open);
3080
4099
  }
3081
4100
  return(res);
3082
4101
}
3083
4102
 
3084
4103
 
3085
 
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
 
4104
bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
3086
4105
{
3087
4106
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3088
4107
 
3089
 
  return(mysql_admin_table(session, tables, check_opt,
 
4108
  return(mysql_admin_table(thd, tables, check_opt,
3090
4109
                                "analyze", lock_type, 1, 0, 0, 0,
3091
4110
                                &handler::ha_analyze));
3092
4111
}
3093
4112
 
3094
4113
 
3095
 
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
 
4114
bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
3096
4115
{
3097
4116
  thr_lock_type lock_type = TL_READ_NO_INSERT;
3098
4117
 
3099
 
  return(mysql_admin_table(session, tables, check_opt,
 
4118
  return(mysql_admin_table(thd, tables, check_opt,
3100
4119
                                "check", lock_type,
3101
4120
                                0, 0, HA_OPEN_FOR_REPAIR, 0,
3102
4121
                                &handler::ha_check));
3105
4124
 
3106
4125
/* table_list should contain just one table */
3107
4126
static int
3108
 
mysql_discard_or_import_tablespace(Session *session,
3109
 
                                   TableList *table_list,
 
4127
mysql_discard_or_import_tablespace(THD *thd,
 
4128
                                   TABLE_LIST *table_list,
3110
4129
                                   enum tablespace_op_type tablespace_op)
3111
4130
{
3112
 
  Table *table;
3113
 
  bool discard;
 
4131
  TABLE *table;
 
4132
  my_bool discard;
3114
4133
  int error;
3115
4134
 
3116
4135
  /*
3117
4136
    Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
3118
 
    ALTER Table
 
4137
    ALTER TABLE
3119
4138
  */
3120
4139
 
3121
 
  session->set_proc_info("discard_or_import_tablespace");
 
4140
  thd_proc_info(thd, "discard_or_import_tablespace");
3122
4141
 
3123
4142
  discard= test(tablespace_op == DISCARD_TABLESPACE);
3124
4143
 
3126
4145
   We set this flag so that ha_innobase::open and ::external_lock() do
3127
4146
   not complain when we lock the table
3128
4147
 */
3129
 
  session->tablespace_op= true;
3130
 
  if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
 
4148
  thd->tablespace_op= true;
 
4149
  if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
3131
4150
  {
3132
 
    session->tablespace_op=false;
 
4151
    thd->tablespace_op=false;
3133
4152
    return(-1);
3134
4153
  }
3135
4154
 
3136
4155
  error= table->file->ha_discard_or_import_tablespace(discard);
3137
4156
 
3138
 
  session->set_proc_info("end");
 
4157
  thd_proc_info(thd, "end");
3139
4158
 
3140
4159
  if (error)
3141
4160
    goto err;
3142
4161
 
3143
 
  /* The ALTER Table is always in its own transaction */
3144
 
  error = ha_autocommit_or_rollback(session, 0);
3145
 
  if (! session->endActiveTransaction())
 
4162
  /* The ALTER TABLE is always in its own transaction */
 
4163
  error = ha_autocommit_or_rollback(thd, 0);
 
4164
  if (end_active_trans(thd))
3146
4165
    error=1;
3147
4166
  if (error)
3148
4167
    goto err;
3149
 
  write_bin_log(session, false, session->query, session->query_length);
 
4168
  write_bin_log(thd, false, thd->query, thd->query_length);
3150
4169
 
3151
4170
err:
3152
 
  ha_autocommit_or_rollback(session, error);
3153
 
  session->tablespace_op=false;
3154
 
 
 
4171
  ha_autocommit_or_rollback(thd, error);
 
4172
  thd->tablespace_op=false;
 
4173
  
3155
4174
  if (error == 0)
3156
4175
  {
3157
 
    session->my_ok();
 
4176
    my_ok(thd);
3158
4177
    return(0);
3159
4178
  }
3160
4179
 
3161
4180
  table->file->print_error(error, MYF(0));
3162
 
 
 
4181
    
3163
4182
  return(-1);
3164
4183
}
3165
4184
 
3169
4188
 
3170
4189
void setup_ha_alter_flags(Alter_info *alter_info, HA_ALTER_FLAGS *alter_flags)
3171
4190
{
3172
 
  uint32_t flags= alter_info->flags;
 
4191
  uint flags= alter_info->flags;
3173
4192
 
3174
4193
  if (ALTER_ADD_COLUMN & flags)
3175
 
    alter_flags->set(HA_ADD_COLUMN);
 
4194
    *alter_flags|= HA_ADD_COLUMN;
3176
4195
  if (ALTER_DROP_COLUMN & flags)
3177
 
    alter_flags->set(HA_DROP_COLUMN);
 
4196
    *alter_flags|= HA_DROP_COLUMN;
3178
4197
  if (ALTER_RENAME & flags)
3179
 
    alter_flags->set(HA_RENAME_TABLE);
 
4198
    *alter_flags|= HA_RENAME_TABLE;
3180
4199
  if (ALTER_CHANGE_COLUMN & flags)
3181
 
    alter_flags->set(HA_CHANGE_COLUMN);
 
4200
    *alter_flags|= HA_CHANGE_COLUMN;
3182
4201
  if (ALTER_COLUMN_DEFAULT & flags)
3183
 
    alter_flags->set(HA_COLUMN_DEFAULT_VALUE);
 
4202
    *alter_flags|= HA_COLUMN_DEFAULT_VALUE;
3184
4203
  if (ALTER_COLUMN_STORAGE & flags)
3185
 
    alter_flags->set(HA_COLUMN_STORAGE);
 
4204
    *alter_flags|= HA_COLUMN_STORAGE;
3186
4205
  if (ALTER_COLUMN_FORMAT & flags)
3187
 
    alter_flags->set(HA_COLUMN_FORMAT);
 
4206
    *alter_flags|= HA_COLUMN_FORMAT;
3188
4207
  if (ALTER_COLUMN_ORDER & flags)
3189
 
    alter_flags->set(HA_ALTER_COLUMN_ORDER);
 
4208
    *alter_flags|= HA_ALTER_COLUMN_ORDER;
3190
4209
  if (ALTER_STORAGE & flags)
3191
 
    alter_flags->set(HA_ALTER_STORAGE);
 
4210
    *alter_flags|= HA_ALTER_STORAGE;
3192
4211
  if (ALTER_ROW_FORMAT & flags)
3193
 
    alter_flags->set(HA_ALTER_ROW_FORMAT);
 
4212
    *alter_flags|= HA_ALTER_ROW_FORMAT;
3194
4213
  if (ALTER_RECREATE & flags)
3195
 
    alter_flags->set(HA_RECREATE);
 
4214
    *alter_flags|= HA_RECREATE;
3196
4215
  if (ALTER_FOREIGN_KEY & flags)
3197
 
    alter_flags->set(HA_ALTER_FOREIGN_KEY);
 
4216
    *alter_flags|= HA_ALTER_FOREIGN_KEY;
3198
4217
}
3199
4218
 
3200
4219
 
3201
4220
/**
3202
 
   @param       session                Thread
 
4221
   @param       thd                Thread
3203
4222
   @param       table              The original table.
3204
4223
   @param       alter_info         Alter options, fields and keys for the new
3205
4224
                                   table.
3214
4233
   table has in arguments create_list, key_list and create_info.
3215
4234
 
3216
4235
   By comparing the changes between the original and new table
3217
 
   we can determine how much it has changed after ALTER Table
 
4236
   we can determine how much it has changed after ALTER TABLE
3218
4237
   and whether we need to make a copy of the table, or just change
3219
4238
   the .frm file.
3220
4239
 
3231
4250
 
3232
4251
static
3233
4252
bool
3234
 
compare_tables(Session *session,
3235
 
               Table *table,
 
4253
compare_tables(THD *thd,
 
4254
               TABLE *table,
3236
4255
               Alter_info *alter_info,
3237
 
               HA_CREATE_INFO *create_info,
3238
 
               uint32_t order_num,
 
4256
                           HA_CREATE_INFO *create_info,
 
4257
               uint order_num,
3239
4258
               HA_ALTER_FLAGS *alter_flags,
3240
4259
               HA_ALTER_INFO *ha_alter_info,
3241
 
               uint32_t *table_changes)
 
4260
               uint *table_changes)
3242
4261
{
3243
4262
  Field **f_ptr, *field;
3244
 
  uint32_t table_changes_local= 0;
 
4263
  uint table_changes_local= 0;
3245
4264
  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
3246
4265
  Create_field *new_field;
3247
4266
  KEY_PART_INFO *key_part;
3248
4267
  KEY_PART_INFO *end;
 
4268
  /*
 
4269
    Remember if the new definition has new VARCHAR column;
 
4270
    create_info->varchar will be reset in mysql_prepare_create_table.
 
4271
  */
 
4272
  bool varchar= create_info->varchar;
3249
4273
 
3250
4274
  {
3251
4275
    /*
3260
4284
      like to keep compare_tables() idempotent (not altering any
3261
4285
      of the arguments) we create a copy of alter_info here and
3262
4286
      pass it to mysql_prepare_create_table, then use the result
3263
 
      to evaluate possibility of fast ALTER Table, and then
 
4287
      to evaluate possibility of fast ALTER TABLE, and then
3264
4288
      destroy the copy.
3265
4289
    */
3266
 
    Alter_info tmp_alter_info(*alter_info, session->mem_root);
3267
 
    session= table->in_use;
3268
 
    uint32_t db_options= 0; /* not used */
 
4290
    Alter_info tmp_alter_info(*alter_info, thd->mem_root);
 
4291
    THD *thd= table->in_use;
 
4292
    uint db_options= 0; /* not used */
3269
4293
    /* Create the prepared information. */
3270
 
    if (mysql_prepare_create_table(session, create_info,
 
4294
    if (mysql_prepare_create_table(thd, create_info,
3271
4295
                                   &tmp_alter_info,
3272
4296
                                   (table->s->tmp_table != NO_TMP_TABLE),
3273
4297
                                   &db_options,
3278
4302
      return(true);
3279
4303
    /* Allocate result buffers. */
3280
4304
    if (! (ha_alter_info->index_drop_buffer=
3281
 
           (uint*) session->alloc(sizeof(uint32_t) * table->s->keys)) ||
 
4305
           (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
3282
4306
        ! (ha_alter_info->index_add_buffer=
3283
 
           (uint*) session->alloc(sizeof(uint32_t) *
 
4307
           (uint*) thd->alloc(sizeof(uint) *
3284
4308
                              tmp_alter_info.key_list.elements)))
3285
4309
      return(true);
3286
4310
  }
3293
4317
 
3294
4318
  /*
3295
4319
    Some very basic checks. If number of fields changes, or the
3296
 
    handler, we need to run full ALTER Table. In the future
 
4320
    handler, we need to run full ALTER TABLE. In the future
3297
4321
    new fields can be added and old dropped without copy, but
3298
4322
    not yet.
3299
4323
 
3300
 
    Test also that engine was not given during ALTER Table, or
 
4324
    Test also that engine was not given during ALTER TABLE, or
3301
4325
    we are force to run regular alter table (copy).
3302
 
    E.g. ALTER Table tbl_name ENGINE=MyISAM.
 
4326
    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
3303
4327
 
3304
4328
    For the following ones we also want to run regular alter table:
3305
 
    ALTER Table tbl_name order_st BY ..
3306
 
    ALTER Table tbl_name CONVERT TO CHARACTER SET ..
 
4329
    ALTER TABLE tbl_name ORDER BY ..
 
4330
    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
3307
4331
 
3308
4332
    At the moment we can't handle altering temporary tables without a copy.
3309
 
    We also test if OPTIMIZE Table was given and was mapped to alter table.
 
4333
    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
3310
4334
    In that case we always do full copy.
3311
4335
 
3312
4336
    There was a bug prior to mysql-4.0.25. Number of null fields was
3326
4350
      create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3327
4351
      (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3328
4352
      order_num ||
3329
 
      !table->s->mysql_version)
 
4353
      !table->s->mysql_version ||
 
4354
      (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
3330
4355
  {
3331
4356
    *table_changes= IS_EQUAL_NO;
3332
4357
    /*
3333
4358
      Check what has changed and set alter_flags
3334
4359
    */
3335
4360
    if (table->s->fields < alter_info->create_list.elements)
3336
 
      alter_flags->set(HA_ADD_COLUMN);
 
4361
      *alter_flags|= HA_ADD_COLUMN;
3337
4362
    else if (table->s->fields > alter_info->create_list.elements)
3338
 
      alter_flags->set(HA_DROP_COLUMN);
 
4363
      *alter_flags|= HA_DROP_COLUMN;
3339
4364
    if (create_info->db_type != table->s->db_type() ||
3340
4365
        create_info->used_fields & HA_CREATE_USED_ENGINE)
3341
 
      alter_flags->set(HA_ALTER_STORAGE_ENGINE);
 
4366
      *alter_flags|= HA_ALTER_STORAGE_ENGINE;
3342
4367
    if (create_info->used_fields & HA_CREATE_USED_CHARSET)
3343
 
      alter_flags->set(HA_CHANGE_CHARACTER_SET);
 
4368
      *alter_flags|= HA_CHANGE_CHARACTER_SET;
3344
4369
    if (create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)
3345
 
      alter_flags->set(HA_SET_DEFAULT_CHARACTER_SET);
 
4370
      *alter_flags|= HA_SET_DEFAULT_CHARACTER_SET;
3346
4371
    if (alter_info->flags & ALTER_RECREATE)
3347
 
      alter_flags->set(HA_RECREATE);
 
4372
      *alter_flags|= HA_RECREATE;
3348
4373
    /* TODO check for ADD/DROP FOREIGN KEY */
3349
4374
    if (alter_info->flags & ALTER_FOREIGN_KEY)
3350
 
      alter_flags->set(HA_ALTER_FOREIGN_KEY);
 
4375
      *alter_flags|=  HA_ALTER_FOREIGN_KEY;
 
4376
    if (!table->s->mysql_version ||
 
4377
        (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
 
4378
      *alter_flags|=  HA_ALTER_COLUMN_TYPE;
3351
4379
  }
3352
4380
  /*
3353
4381
    Go through fields and check if the original ones are compatible
3364
4392
    /* Don't pack rows in old tables if the user has requested this. */
3365
4393
    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
3366
4394
        (new_field->flags & BLOB_FLAG) ||
3367
 
        (new_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
 
4395
        (new_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED))
3368
4396
      create_info->table_options|= HA_OPTION_PACK_RECORD;
3369
4397
 
3370
4398
    /* Check how fields have been modified */
3372
4400
    {
3373
4401
      /* Evaluate changes bitmap and send to check_if_incompatible_data() */
3374
4402
      if (!(table_changes_local= field->is_equal(new_field)))
3375
 
        alter_flags->set(HA_ALTER_COLUMN_TYPE);
3376
 
 
3377
 
      /*
3378
 
        Check if the altered column is a stored virtual field.
3379
 
        TODO: Mark such a column with an alter flag only if
3380
 
        the expression functions are not equal.
3381
 
      */
3382
 
      if (field->is_stored && field->vcol_info)
3383
 
        alter_flags->set(HA_ALTER_STORED_VCOL);
 
4403
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3384
4404
 
3385
4405
      /* Check if field was renamed */
3386
4406
      field->flags&= ~FIELD_IS_RENAMED;
3389
4409
                        new_field->field_name))
3390
4410
      {
3391
4411
        field->flags|= FIELD_IS_RENAMED;
3392
 
        alter_flags->set(HA_ALTER_COLUMN_NAME);
 
4412
        *alter_flags|= HA_ALTER_COLUMN_NAME;
3393
4413
      }
3394
4414
 
3395
4415
      *table_changes&= table_changes_local;
3396
4416
      if (table_changes_local == IS_EQUAL_PACK_LENGTH)
3397
 
        alter_flags->set(HA_ALTER_COLUMN_TYPE);
 
4417
        *alter_flags|= HA_ALTER_COLUMN_TYPE;
3398
4418
 
3399
4419
      /* Check that NULL behavior is same for old and new fields */
3400
4420
      if ((new_field->flags & NOT_NULL_FLAG) !=
3401
 
          (uint32_t) (field->flags & NOT_NULL_FLAG))
 
4421
          (uint) (field->flags & NOT_NULL_FLAG))
3402
4422
      {
3403
4423
        *table_changes= IS_EQUAL_NO;
3404
 
        alter_flags->set(HA_ALTER_COLUMN_NULLABLE);
 
4424
        *alter_flags|= HA_ALTER_COLUMN_NULLABLE;
3405
4425
      }
3406
4426
    }
3407
4427
 
3447
4467
      if (table_key->flags & HA_NOSAME)
3448
4468
      {
3449
4469
        /* Unique key. Check for "PRIMARY". */
3450
 
        if (is_primary_key(table_key))
3451
 
          alter_flags->set(HA_DROP_PK_INDEX);
 
4470
        if (! my_strcasecmp(system_charset_info,
 
4471
                            table_key->name, primary_key_name))
 
4472
          *alter_flags|= HA_DROP_PK_INDEX;
3452
4473
        else
3453
 
          alter_flags->set(HA_DROP_UNIQUE_INDEX);
 
4474
          *alter_flags|= HA_DROP_UNIQUE_INDEX;
3454
4475
      }
3455
4476
      else
3456
 
        alter_flags->set(HA_DROP_INDEX);
 
4477
        *alter_flags|= HA_DROP_INDEX;
3457
4478
      *table_changes= IS_EQUAL_NO;
3458
4479
      continue;
3459
4480
    }
3467
4488
      if (table_key->flags & HA_NOSAME)
3468
4489
      {
3469
4490
        // Unique key. Check for "PRIMARY".
3470
 
        if (is_primary_key(table_key))
3471
 
          alter_flags->set(HA_ALTER_PK_INDEX);
 
4491
        if (! my_strcasecmp(system_charset_info,
 
4492
                            table_key->name, primary_key_name))
 
4493
          *alter_flags|= HA_ALTER_PK_INDEX;
3472
4494
        else
3473
 
          alter_flags->set(HA_ALTER_UNIQUE_INDEX);
 
4495
          *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3474
4496
      }
3475
4497
      else
3476
 
        alter_flags->set(HA_ALTER_INDEX);
 
4498
        *alter_flags|= HA_ALTER_INDEX;
3477
4499
      goto index_changed;
3478
4500
    }
3479
4501
 
3496
4518
        if (table_key->flags & HA_NOSAME)
3497
4519
        {
3498
4520
          /* Unique key. Check for "PRIMARY" */
3499
 
          if (is_primary_key(table_key))
3500
 
            alter_flags->set(HA_ALTER_PK_INDEX);
 
4521
          if (! my_strcasecmp(system_charset_info,
 
4522
                              table_key->name, primary_key_name))
 
4523
            *alter_flags|= HA_ALTER_PK_INDEX;
3501
4524
          else
3502
 
            alter_flags->set(HA_ALTER_UNIQUE_INDEX);
 
4525
            *alter_flags|= HA_ALTER_UNIQUE_INDEX;
3503
4526
        }
3504
4527
        else
3505
 
          alter_flags->set(HA_ALTER_INDEX);
 
4528
          *alter_flags|= HA_ALTER_INDEX;
3506
4529
        goto index_changed;
3507
4530
      }
3508
4531
    }
3558
4581
      if (new_key->flags & HA_NOSAME)
3559
4582
      {
3560
4583
        /* Unique key. Check for "PRIMARY" */
3561
 
        if (is_primary_key(new_key))
3562
 
          alter_flags->set(HA_ADD_PK_INDEX);
 
4584
        if (! my_strcasecmp(system_charset_info,
 
4585
                            new_key->name, primary_key_name))
 
4586
          *alter_flags|= HA_ADD_PK_INDEX;
3563
4587
        else
3564
 
        alter_flags->set(HA_ADD_UNIQUE_INDEX);
 
4588
        *alter_flags|= HA_ADD_UNIQUE_INDEX;
3565
4589
      }
3566
4590
      else
3567
 
        alter_flags->set(HA_ADD_INDEX);
 
4591
        *alter_flags|= HA_ADD_INDEX;
3568
4592
      *table_changes= IS_EQUAL_NO;
3569
4593
    }
3570
4594
  }
3574
4598
 
3575
4599
 
3576
4600
/*
3577
 
  Manages enabling/disabling of indexes for ALTER Table
 
4601
  Manages enabling/disabling of indexes for ALTER TABLE
3578
4602
 
3579
4603
  SYNOPSIS
3580
4604
    alter_table_manage_keys()
3589
4613
*/
3590
4614
 
3591
4615
static
3592
 
bool alter_table_manage_keys(Table *table, int indexes_were_disabled,
 
4616
bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
3593
4617
                             enum enum_enable_or_disable keys_onoff)
3594
4618
{
3595
4619
  int error= 0;
3607
4631
 
3608
4632
  if (error == HA_ERR_WRONG_COMMAND)
3609
4633
  {
3610
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
4634
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
3611
4635
                        ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
3612
4636
                        table->s->table_name.str);
3613
4637
    error= 0;
3617
4641
  return(error);
3618
4642
}
3619
4643
 
3620
 
int create_temporary_table(Session *session,
3621
 
                           Table *table,
 
4644
int create_temporary_table(THD *thd,
 
4645
                           TABLE *table,
3622
4646
                           char *new_db,
3623
4647
                           char *tmp_name,
3624
4648
                           HA_CREATE_INFO *create_info,
3627
4651
{
3628
4652
  int error;
3629
4653
  char index_file[FN_REFLEN], data_file[FN_REFLEN];
3630
 
  StorageEngine *old_db_type, *new_db_type;
 
4654
  handlerton *old_db_type, *new_db_type;
3631
4655
  old_db_type= table->s->db_type();
3632
4656
  new_db_type= create_info->db_type;
3633
4657
  /*
3659
4683
    if (create_info->index_file_name)
3660
4684
    {
3661
4685
      /* Fix index_file_name to have 'tmp_name' as basename */
3662
 
      strcpy(index_file, tmp_name);
 
4686
      strmov(index_file, tmp_name);
3663
4687
      create_info->index_file_name=fn_same(index_file,
3664
4688
                                           create_info->index_file_name,
3665
4689
                                           1);
3667
4691
    if (create_info->data_file_name)
3668
4692
    {
3669
4693
      /* Fix data_file_name to have 'tmp_name' as basename */
3670
 
      strcpy(data_file, tmp_name);
 
4694
      strmov(data_file, tmp_name);
3671
4695
      create_info->data_file_name=fn_same(data_file,
3672
4696
                                          create_info->data_file_name,
3673
4697
                                          1);
3678
4702
 
3679
4703
  /*
3680
4704
    Create a table with a temporary name.
 
4705
    With create_info->frm_only == 1 this creates a .frm file only.
3681
4706
    We don't log the statement, it will be logged later.
3682
4707
  */
3683
 
  error= mysql_create_table(session, new_db, tmp_name,
 
4708
  tmp_disable_binlog(thd);
 
4709
  error= mysql_create_table(thd, new_db, tmp_name,
3684
4710
                            create_info, alter_info, 1, 0);
 
4711
  reenable_binlog(thd);
3685
4712
 
3686
4713
  return(error);
3687
4714
}
3692
4719
 
3693
4720
  SYNOPSIS
3694
4721
    create_altered_table()
3695
 
      session              Thread handle
 
4722
      thd              Thread handle
3696
4723
      table            The original table
3697
4724
      create_info      Information from the parsing phase about new
3698
4725
                       table properties.
3706
4733
    The temporary table is created without storing it in any storage engine
3707
4734
    and is opened only to get the table struct and frm file reference.
3708
4735
*/
3709
 
Table *create_altered_table(Session *session,
3710
 
                            Table *table,
 
4736
TABLE *create_altered_table(THD *thd,
 
4737
                            TABLE *table,
3711
4738
                            char *new_db,
3712
4739
                            HA_CREATE_INFO *create_info,
3713
4740
                            Alter_info *alter_info,
3715
4742
{
3716
4743
  int error;
3717
4744
  HA_CREATE_INFO altered_create_info(*create_info);
3718
 
  Table *altered_table;
 
4745
  TABLE *altered_table;
3719
4746
  char tmp_name[80];
3720
4747
  char path[FN_REFLEN];
3721
4748
 
3722
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
3723
 
           TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
 
4749
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
 
4750
           tmp_file_prefix, current_pid, thd->thread_id);
3724
4751
  /* Safety fix for InnoDB */
3725
4752
  if (lower_case_table_names)
3726
4753
    my_casedn_str(files_charset_info, tmp_name);
3727
4754
  altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
3728
 
 
3729
 
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
 
4755
  altered_create_info.frm_only= 1;
 
4756
  if ((error= create_temporary_table(thd, table, new_db, tmp_name,
3730
4757
                                     &altered_create_info,
3731
4758
                                     alter_info, db_change)))
3732
4759
  {
3735
4762
 
3736
4763
  build_table_filename(path, sizeof(path), new_db, tmp_name, "",
3737
4764
                       FN_IS_TMP);
3738
 
  altered_table= open_temporary_table(session, path, new_db, tmp_name, 1,
 
4765
  altered_table= open_temporary_table(thd, path, new_db, tmp_name, 1,
3739
4766
                                      OTM_ALTER);
3740
4767
  return(altered_table);
 
4768
 
 
4769
  return(NULL);
3741
4770
}
3742
4771
 
3743
4772
 
3746
4775
 
3747
4776
  SYNOPSIS
3748
4777
    mysql_fast_or_online_alter_table()
3749
 
      session              Thread handle
 
4778
      thd              Thread handle
3750
4779
      table            The original table
3751
4780
      altered_table    A temporary table showing how we will change table
3752
4781
      create_info      Information from the parsing phase about new
3766
4795
    operation directly, on-line without mysql having to copy
3767
4796
    the table.
3768
4797
*/
3769
 
int mysql_fast_or_online_alter_table(Session *session,
3770
 
                                     Table *table,
3771
 
                                     Table *altered_table,
 
4798
int mysql_fast_or_online_alter_table(THD *thd,
 
4799
                                     TABLE *table,
 
4800
                                     TABLE *altered_table,
3772
4801
                                     HA_CREATE_INFO *create_info,
3773
4802
                                     HA_ALTER_INFO *alter_info,
3774
4803
                                     HA_ALTER_FLAGS *ha_alter_flags,
3776
4805
{
3777
4806
  int error= 0;
3778
4807
  bool online= (table->file->ha_table_flags() & HA_ONLINE_ALTER)?true:false;
3779
 
  Table *t_table;
 
4808
  TABLE *t_table;
3780
4809
 
3781
4810
  if (online)
3782
4811
  {
3783
4812
   /*
3784
4813
      Tell the handler to prepare for the online alter
3785
4814
    */
3786
 
    if ((error= table->file->alter_table_phase1(session,
 
4815
    if ((error= table->file->alter_table_phase1(thd,
3787
4816
                                                altered_table,
3788
4817
                                                create_info,
3789
4818
                                                alter_info,
3794
4823
 
3795
4824
    /*
3796
4825
       Tell the storage engine to perform the online alter table
3797
 
       TODO:
 
4826
       TODO: 
3798
4827
       if check_if_supported_alter() returned HA_ALTER_SUPPORTED_WAIT_LOCK
3799
4828
       we need to wrap the next call with a DDL lock.
3800
4829
     */
3801
 
    if ((error= table->file->alter_table_phase2(session,
 
4830
    if ((error= table->file->alter_table_phase2(thd,
3802
4831
                                                altered_table,
3803
4832
                                                create_info,
3804
4833
                                                alter_info,
3811
4840
    The final .frm file is already created as a temporary file
3812
4841
    and will be renamed to the original table name.
3813
4842
  */
3814
 
  pthread_mutex_lock(&LOCK_open);
3815
 
  wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
 
4843
  VOID(pthread_mutex_lock(&LOCK_open));
 
4844
  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3816
4845
  alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3817
4846
                          keys_onoff);
3818
 
  close_data_files_and_morph_locks(session,
 
4847
  close_data_files_and_morph_locks(thd,
3819
4848
                                   table->pos_in_table_list->db,
3820
4849
                                   table->pos_in_table_list->table_name);
3821
4850
  if (mysql_rename_table(NULL,
3825
4854
                         table->s->table_name.str, FN_FROM_IS_TMP))
3826
4855
  {
3827
4856
    error= 1;
3828
 
    pthread_mutex_unlock(&LOCK_open);
 
4857
    VOID(pthread_mutex_unlock(&LOCK_open));
3829
4858
    goto err;
3830
4859
  }
3831
4860
  broadcast_refresh();
3832
 
  pthread_mutex_unlock(&LOCK_open);
 
4861
  VOID(pthread_mutex_unlock(&LOCK_open));
3833
4862
 
3834
4863
  /*
3835
 
    The ALTER Table is always in its own transaction.
 
4864
    The ALTER TABLE is always in its own transaction.
3836
4865
    Commit must not be called while LOCK_open is locked. It could call
3837
4866
    wait_if_global_read_lock(), which could create a deadlock if called
3838
4867
    with LOCK_open.
3839
4868
  */
3840
 
  error= ha_autocommit_or_rollback(session, 0);
 
4869
  error= ha_autocommit_or_rollback(thd, 0);
3841
4870
 
3842
 
  if (ha_commit(session))
 
4871
  if (ha_commit(thd))
3843
4872
    error=1;
3844
4873
  if (error)
3845
4874
    goto err;
3846
4875
  if (online)
3847
4876
  {
3848
 
    pthread_mutex_lock(&LOCK_open);
 
4877
    VOID(pthread_mutex_lock(&LOCK_open));
3849
4878
    if (reopen_table(table))
3850
4879
    {
3851
4880
      error= -1;
3852
4881
      goto err;
3853
4882
    }
3854
 
    pthread_mutex_unlock(&LOCK_open);
 
4883
    VOID(pthread_mutex_unlock(&LOCK_open));
3855
4884
    t_table= table;
3856
4885
 
3857
4886
   /*
3858
4887
      Tell the handler that the changed frm is on disk and table
3859
4888
      has been re-opened
3860
4889
   */
3861
 
    if ((error= t_table->file->alter_table_phase3(session, t_table)))
 
4890
    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
3862
4891
    {
3863
4892
      goto err;
3864
4893
    }
3865
4894
 
3866
4895
    /*
3867
4896
      We are going to reopen table down on the road, so we have to restore
3868
 
      state of the Table object which we used for obtaining of handler
 
4897
      state of the TABLE object which we used for obtaining of handler
3869
4898
      object to make it suitable for reopening.
3870
4899
    */
3871
4900
    assert(t_table == table);
3872
4901
    table->open_placeholder= 1;
3873
 
    pthread_mutex_lock(&LOCK_open);
 
4902
    VOID(pthread_mutex_lock(&LOCK_open));
3874
4903
    close_handle_and_leave_table_as_lock(table);
3875
 
    pthread_mutex_unlock(&LOCK_open);
 
4904
    VOID(pthread_mutex_unlock(&LOCK_open));
3876
4905
  }
3877
4906
 
3878
4907
 err:
3883
4912
 
3884
4913
 
3885
4914
/**
3886
 
  Prepare column and key definitions for CREATE TABLE in ALTER Table.
 
4915
  Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
3887
4916
 
3888
 
  This function transforms parse output of ALTER Table - lists of
 
4917
  This function transforms parse output of ALTER TABLE - lists of
3889
4918
  columns and keys to add, drop or modify into, essentially,
3890
4919
  CREATE TABLE definition - a list of columns and keys of the new
3891
4920
  table. While doing so, it also performs some (bug not all)
3892
4921
  semantic checks.
3893
4922
 
3894
4923
  This function is invoked when we know that we're going to
3895
 
  perform ALTER Table via a temporary table -- i.e. fast ALTER Table
 
4924
  perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
3896
4925
  is not possible, perhaps because the ALTER statement contains
3897
4926
  instructions that require change in table data, not only in
3898
4927
  table definition or indexes.
3899
4928
 
3900
 
  @param[in,out]  session         thread handle. Used as a memory pool
 
4929
  @param[in,out]  thd         thread handle. Used as a memory pool
3901
4930
                              and source of environment information.
3902
4931
  @param[in]      table       the source table, open and locked
3903
4932
                              Used as an interface to the storage engine
3904
4933
                              to acquire additional information about
3905
4934
                              the original table.
3906
 
  @param[in,out]  create_info A blob with CREATE/ALTER Table
 
4935
  @param[in,out]  create_info A blob with CREATE/ALTER TABLE
3907
4936
                              parameters
3908
4937
  @param[in,out]  alter_info  Another blob with ALTER/CREATE parameters.
3909
4938
                              Originally create_info was used only in
3910
 
                              CREATE TABLE and alter_info only in ALTER Table.
 
4939
                              CREATE TABLE and alter_info only in ALTER TABLE.
3911
4940
                              But since ALTER might end-up doing CREATE,
3912
4941
                              this distinction is gone and we just carry
3913
4942
                              around two structures.
3919
4948
    Prepares alter_info->create_list and alter_info->key_list with
3920
4949
    columns and keys of the new table.
3921
4950
  @retval true   error, out of memory or a semantical error in ALTER
3922
 
                 Table instructions
 
4951
                 TABLE instructions
3923
4952
  @retval false  success
3924
4953
*/
3925
4954
 
3926
4955
static bool
3927
 
mysql_prepare_alter_table(Session *session, Table *table,
 
4956
mysql_prepare_alter_table(THD *thd, TABLE *table,
3928
4957
                          HA_CREATE_INFO *create_info,
3929
4958
                          Alter_info *alter_info)
3930
4959
{
3939
4968
  List_iterator<Create_field> find_it(new_create_list);
3940
4969
  List_iterator<Create_field> field_it(new_create_list);
3941
4970
  List<Key_part_spec> key_parts;
3942
 
  uint32_t db_create_options= (table->s->db_create_options
 
4971
  uint db_create_options= (table->s->db_create_options
3943
4972
                           & ~(HA_OPTION_PACK_RECORD));
3944
 
  uint32_t used_fields= create_info->used_fields;
 
4973
  uint used_fields= create_info->used_fields;
3945
4974
  KEY *key_info=table->key_info;
3946
4975
  bool rc= true;
3947
4976
 
3954
4983
    create_info->max_rows= table->s->max_rows;
3955
4984
  if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
3956
4985
    create_info->avg_row_length= table->s->avg_row_length;
3957
 
  if (!(used_fields & HA_CREATE_USED_BLOCK_SIZE))
3958
 
    create_info->block_size= table->s->block_size;
3959
4986
  if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
3960
4987
    create_info->default_table_charset= table->s->table_charset;
3961
4988
  if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
3966
4993
  }
3967
4994
  if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
3968
4995
    create_info->key_block_size= table->s->key_block_size;
 
4996
  if (!(used_fields & HA_CREATE_USED_TRANSACTIONAL))
 
4997
    create_info->transactional= table->s->transactional;
3969
4998
 
3970
4999
  restore_record(table, s->default_values);     // Empty record for DEFAULT
3971
5000
  Create_field *def;
3975
5004
    */
3976
5005
  Field **f_ptr,*field;
3977
5006
  for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
3978
 
  {
 
5007
    {
 
5008
    if (field->type() == MYSQL_TYPE_STRING)
 
5009
      create_info->varchar= true;
3979
5010
    /* Check if field should be dropped */
3980
5011
    Alter_drop *drop;
3981
5012
    drop_it.rewind();
3983
5014
    {
3984
5015
      if (drop->type == Alter_drop::COLUMN &&
3985
5016
          !my_strcasecmp(system_charset_info,field->field_name, drop->name))
3986
 
      {
 
5017
    {
3987
5018
        /* Reset auto_increment value if it was dropped */
3988
5019
        if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
3989
5020
            !(used_fields & HA_CREATE_USED_AUTO))
3990
 
        {
 
5021
      {
3991
5022
          create_info->auto_increment_value=0;
3992
5023
          create_info->used_fields|=HA_CREATE_USED_AUTO;
3993
 
        }
 
5024
      }
3994
5025
        break;
3995
 
      }
3996
5026
    }
 
5027
  }
3997
5028
    if (drop)
3998
 
    {
 
5029
      {
3999
5030
      drop_it.remove();
4000
5031
      continue;
4001
5032
    }
4010
5041
    if (def)
4011
5042
    {                                           // Field is changed
4012
5043
      def->field=field;
4013
 
      if (field->is_stored != def->is_stored)
4014
 
      {
4015
 
        my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
4016
 
                 MYF(0),
4017
 
                 "Changing the STORED status");
4018
 
        goto err;
4019
 
      }
4020
5044
      if (!def->after)
4021
 
      {
 
5045
        {
4022
5046
        new_create_list.push_back(def);
4023
5047
        def_it.remove();
 
5048
        }
4024
5049
      }
4025
 
    }
4026
 
    else
4027
 
    {
 
5050
      else
 
5051
      {
4028
5052
      /*
4029
5053
        This field was not dropped and not changed, add it to the list
4030
5054
        for the new table.
4034
5058
      alter_it.rewind();                        // Change default if ALTER
4035
5059
      Alter_column *alter;
4036
5060
      while ((alter=alter_it++))
4037
 
      {
 
5061
        {
4038
5062
        if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
4039
5063
          break;
4040
 
      }
 
5064
        }
4041
5065
      if (alter)
4042
 
      {
4043
 
        if (def->sql_type == DRIZZLE_TYPE_BLOB)
 
5066
        {
 
5067
        if (def->sql_type == MYSQL_TYPE_BLOB)
4044
5068
        {
4045
5069
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
4046
5070
          goto err;
4061
5085
      my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
4062
5086
      goto err;
4063
5087
    }
4064
 
    /*
 
5088
      /*
4065
5089
      Check that the DATE/DATETIME not null field we are going to add is
4066
5090
      either has a default value or the '0000-00-00' is allowed by the
4067
5091
      set sql mode.
4068
5092
      If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4069
 
      flag to allow ALTER Table only if the table to be altered is empty.
4070
 
    */
4071
 
    if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4072
 
         def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4073
 
        !alter_info->datetime_field &&
4074
 
        !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4075
 
        session->variables.sql_mode & MODE_NO_ZERO_DATE)
 
5093
      flag to allow ALTER TABLE only if the table to be altered is empty.
 
5094
      */
 
5095
    if ((def->sql_type == MYSQL_TYPE_NEWDATE ||
 
5096
         def->sql_type == MYSQL_TYPE_DATETIME) &&
 
5097
         !alter_info->datetime_field &&
 
5098
         !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
 
5099
         thd->variables.sql_mode & MODE_NO_ZERO_DATE)
4076
5100
    {
4077
 
      alter_info->datetime_field= def;
4078
 
      alter_info->error_if_not_empty= true;
 
5101
        alter_info->datetime_field= def;
 
5102
        alter_info->error_if_not_empty= true;
4079
5103
    }
4080
5104
    if (!def->after)
4081
5105
      new_create_list.push_back(def);
4089
5113
      {
4090
5114
        if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
4091
5115
          break;
4092
 
      }
 
5116
  }
4093
5117
      if (!find)
4094
 
      {
 
5118
  {
4095
5119
        my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
4096
 
        goto err;
4097
 
      }
 
5120
    goto err;
 
5121
  }
4098
5122
      find_it.after(def);                       // Put element after this
4099
5123
      /*
4100
5124
        XXX: hack for Bug#28427.
4101
 
        If column order has changed, force OFFLINE ALTER Table
 
5125
        If column order has changed, force OFFLINE ALTER TABLE
4102
5126
        without querying engine capabilities.  If we ever have an
4103
 
        engine that supports online ALTER Table CHANGE COLUMN
 
5127
        engine that supports online ALTER TABLE CHANGE COLUMN
4104
5128
        <name> AFTER <name1> (Falcon?), this fix will effectively
4105
5129
        disable the capability.
4106
5130
        TODO: detect the situation in compare_tables, behave based
4108
5132
      */
4109
5133
      if (alter_info->build_method == HA_BUILD_ONLINE)
4110
5134
      {
4111
 
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
 
5135
        my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4112
5136
        goto err;
4113
5137
      }
4114
5138
      alter_info->build_method= HA_BUILD_OFFLINE;
4119
5143
    my_error(ER_BAD_FIELD_ERROR, MYF(0),
4120
5144
             alter_info->alter_list.head()->name, table->s->table_name.str);
4121
5145
    goto err;
4122
 
  }
 
5146
    }
4123
5147
  if (!new_create_list.elements)
4124
 
  {
 
5148
    {
4125
5149
    my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS),
4126
5150
               MYF(0));
4127
5151
    goto err;
4128
 
  }
 
5152
    }
4129
5153
 
4130
 
  /*
 
5154
    /*
4131
5155
    Collect all keys which isn't in drop list. Add only those
4132
5156
    for which some fields exists.
4133
 
  */
 
5157
    */
4134
5158
 
4135
 
  for (uint32_t i=0 ; i < table->s->keys ; i++,key_info++)
4136
 
  {
 
5159
  for (uint i=0 ; i < table->s->keys ; i++,key_info++)
 
5160
    {
4137
5161
    char *key_name= key_info->name;
4138
5162
    Alter_drop *drop;
4139
5163
    drop_it.rewind();
4140
5164
    while ((drop=drop_it++))
4141
 
    {
 
5165
      {
4142
5166
      if (drop->type == Alter_drop::KEY &&
4143
5167
          !my_strcasecmp(system_charset_info,key_name, drop->name))
4144
5168
        break;
4145
 
    }
 
5169
      }
4146
5170
    if (drop)
4147
 
    {
 
5171
        {
4148
5172
      drop_it.remove();
4149
5173
      continue;
4150
5174
    }
4151
5175
 
4152
5176
    KEY_PART_INFO *key_part= key_info->key_part;
4153
5177
    key_parts.empty();
4154
 
    for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
 
5178
    for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
4155
5179
    {
4156
5180
      if (!key_part->field)
4157
5181
        continue;                               // Wrong field (from UNIREG)
4159
5183
      Create_field *cfield;
4160
5184
      field_it.rewind();
4161
5185
      while ((cfield=field_it++))
4162
 
      {
 
5186
    {
4163
5187
        if (cfield->change)
4164
 
        {
 
5188
    {
4165
5189
          if (!my_strcasecmp(system_charset_info, key_part_name,
4166
5190
                             cfield->change))
4167
5191
            break;
4172
5196
      }
4173
5197
      if (!cfield)
4174
5198
        continue;                               // Field is removed
4175
 
      uint32_t key_part_length=key_part->length;
 
5199
      uint key_part_length=key_part->length;
4176
5200
      if (cfield->field)                        // Not new field
4177
5201
      {
4178
5202
        /*
4205
5229
      KEY_CREATE_INFO key_create_info;
4206
5230
      Key *key;
4207
5231
      enum Key::Keytype key_type;
4208
 
      memset(&key_create_info, 0, sizeof(key_create_info));
 
5232
      bzero((char*) &key_create_info, sizeof(key_create_info));
4209
5233
 
4210
5234
      key_create_info.algorithm= key_info->algorithm;
4211
5235
      if (key_info->flags & HA_USES_BLOCK_SIZE)
4215
5239
 
4216
5240
      if (key_info->flags & HA_NOSAME)
4217
5241
      {
4218
 
        if (is_primary_key_name(key_name))
 
5242
        if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
4219
5243
          key_type= Key::PRIMARY;
4220
5244
        else
4221
5245
          key_type= Key::UNIQUE;
4234
5258
    Key *key;
4235
5259
    while ((key=key_it++))                      // Add new keys
4236
5260
    {
4237
 
      if (key->type == Key::FOREIGN_KEY &&
4238
 
          ((Foreign_key *)key)->validate(new_create_list))
4239
 
        goto err;
4240
5261
      if (key->type != Key::FOREIGN_KEY)
4241
5262
        new_key_list.push_back(key);
4242
 
      if (key->name.str && is_primary_key_name(key->name.str))
 
5263
      if (key->name.str &&
 
5264
          !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
4243
5265
      {
4244
5266
        my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
4245
5267
        goto err;
4296
5318
 
4297
5319
  SYNOPSIS
4298
5320
    mysql_alter_table()
4299
 
      session              Thread handle
 
5321
      thd              Thread handle
4300
5322
      new_db           If there is a RENAME clause
4301
5323
      new_name         If there is a RENAME clause
4302
5324
      create_info      Information from the parsing phase about new
4304
5326
      table_list       The table to change.
4305
5327
      alter_info       Lists of fields, keys to be changed, added
4306
5328
                       or dropped.
4307
 
      order_num        How many order_st BY fields has been specified.
4308
 
      order            List of fields to order_st BY.
4309
 
      ignore           Whether we have ALTER IGNORE Table
 
5329
      order_num        How many ORDER BY fields has been specified.
 
5330
      order            List of fields to ORDER BY.
 
5331
      ignore           Whether we have ALTER IGNORE TABLE
4310
5332
 
4311
5333
  DESCRIPTION
4312
5334
    This is a veery long function and is everything but the kitchen sink :)
4313
 
    It is used to alter a table and not only by ALTER Table but also
 
5335
    It is used to alter a table and not only by ALTER TABLE but also
4314
5336
    CREATE|DROP INDEX are mapped on this function.
4315
5337
 
4316
 
    When the ALTER Table statement just does a RENAME or ENABLE|DISABLE KEYS,
 
5338
    When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
4317
5339
    or both, then this function short cuts its operation by renaming
4318
5340
    the table and/or enabling/disabling the keys. In this case, the FRM is
4319
5341
    not changed, directly by mysql_alter_table. However, if there is a
4333
5355
    true   Error
4334
5356
*/
4335
5357
 
4336
 
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
 
5358
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
4337
5359
                       HA_CREATE_INFO *create_info,
4338
 
                       TableList *table_list,
 
5360
                       TABLE_LIST *table_list,
4339
5361
                       Alter_info *alter_info,
4340
 
                       uint32_t order_num, order_st *order, bool ignore)
 
5362
                       uint order_num, ORDER *order, bool ignore)
4341
5363
{
4342
 
  Table *table, *new_table=0, *name_lock= 0;;
4343
 
  string new_name_str;
 
5364
  TABLE *table, *new_table=0, *name_lock= 0;;
4344
5365
  int error= 0;
4345
5366
  char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4346
5367
  char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4347
5368
  char path[FN_REFLEN];
4348
5369
  ha_rows copied= 0,deleted= 0;
4349
 
  StorageEngine *old_db_type, *new_db_type, *save_old_db_type;
4350
 
 
4351
 
  new_name_buff[0]= '\0';
 
5370
  handlerton *old_db_type, *new_db_type, *save_old_db_type;
 
5371
  legacy_db_type table_type;
 
5372
  frm_type_enum frm_type;
4352
5373
 
4353
5374
  if (table_list && table_list->schema_table)
4354
5375
  {
4355
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
5376
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
4356
5377
    return(true);
4357
5378
  }
4358
5379
 
4361
5382
    to simplify further comparisons: we want to see if it's a RENAME
4362
5383
    later just by comparing the pointers, avoiding the need for strcmp.
4363
5384
  */
4364
 
  session->set_proc_info("init");
 
5385
  thd_proc_info(thd, "init");
4365
5386
  table_name=table_list->table_name;
4366
5387
  alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
4367
5388
  db=table_list->db;
4369
5390
    new_db= db;
4370
5391
  build_table_filename(path, sizeof(path), db, table_name, "", 0);
4371
5392
 
4372
 
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
 
5393
  mysql_ha_rm_tables(thd, table_list, false);
 
5394
 
 
5395
  /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
4373
5396
  if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4374
5397
    /* Conditionally writes to binlog. */
4375
 
    return(mysql_discard_or_import_tablespace(session,table_list,
 
5398
    return(mysql_discard_or_import_tablespace(thd,table_list,
4376
5399
                                              alter_info->tablespace_op));
4377
 
  ostringstream oss;
4378
 
  oss << drizzle_data_home << "/" << db << "/" << table_name;
4379
 
 
4380
 
  (void) unpack_filename(new_name_buff, oss.str().c_str());
 
5400
  strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, 
 
5401
           "/", table_name, reg_ext, NullS);
 
5402
  (void) unpack_filename(new_name_buff, new_name_buff);
4381
5403
  /*
4382
5404
    If this is just a rename of a view, short cut to the
4383
5405
    following scenario: 1) lock LOCK_open 2) do a RENAME
4384
5406
    2) unlock LOCK_open.
4385
5407
    This is a copy-paste added to make sure
4386
 
    ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
 
5408
    ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
4387
5409
    as an independent branch in mysql_execute_command. The need
4388
 
    for a copy-paste arose because the main code flow of ALTER Table
 
5410
    for a copy-paste arose because the main code flow of ALTER TABLE
4389
5411
    ... RENAME tries to use open_ltable, which does not work for views
4390
5412
    (open_ltable was never modified to merge table lists of child tables
4391
5413
    into the main table list, like open_tables does).
4392
5414
    This code is wrong and will be removed, please do not copy.
4393
5415
  */
 
5416
  frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
4394
5417
 
4395
 
  if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
 
5418
  if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
4396
5419
    return(true);
4397
5420
  table->use_all_columns();
4398
5421
 
 
5422
  /*
 
5423
    Prohibit changing of the UNION list of a non-temporary MERGE table
 
5424
    under LOCK tables. It would be quite difficult to reuse a shrinked
 
5425
    set of tables from the old table or to open a new TABLE object for
 
5426
    an extended list and verify that they belong to locked tables.
 
5427
  */
 
5428
  if (thd->locked_tables &&
 
5429
      (create_info->used_fields & HA_CREATE_USED_UNION) &&
 
5430
      (table->s->tmp_table == NO_TMP_TABLE))
 
5431
  {
 
5432
    my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
5433
    return(true);
 
5434
  }
 
5435
 
4399
5436
  /* Check that we are not trying to rename to an existing table */
4400
5437
  if (new_name)
4401
5438
  {
4402
 
    strcpy(new_name_buff,new_name);
4403
 
    strcpy(new_alias= new_alias_buff, new_name);
 
5439
    strmov(new_name_buff,new_name);
 
5440
    strmov(new_alias= new_alias_buff, new_name);
4404
5441
    if (lower_case_table_names)
4405
5442
    {
4406
5443
      if (lower_case_table_names != 2)
4407
5444
      {
4408
 
        my_casedn_str(files_charset_info, new_name_buff);
4409
 
        new_alias= new_name;                    // Create lower case table name
 
5445
        my_casedn_str(files_charset_info, new_name_buff);
 
5446
        new_alias= new_name;                    // Create lower case table name
4410
5447
      }
4411
5448
      my_casedn_str(files_charset_info, new_name);
4412
5449
    }
4423
5460
    {
4424
5461
      if (table->s->tmp_table != NO_TMP_TABLE)
4425
5462
      {
4426
 
        if (find_temporary_table(session,new_db,new_name_buff))
 
5463
        if (find_temporary_table(thd,new_db,new_name_buff))
4427
5464
        {
4428
5465
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
4429
5466
          return(true);
4431
5468
      }
4432
5469
      else
4433
5470
      {
4434
 
        if (lock_table_name_if_not_cached(session, new_db, new_name, &name_lock))
 
5471
        if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
4435
5472
          return(true);
4436
5473
        if (!name_lock)
4437
5474
        {
4440
5477
        }
4441
5478
 
4442
5479
        build_table_filename(new_name_buff, sizeof(new_name_buff),
4443
 
                             new_db, new_name_buff, "", 0);
4444
 
        if (table_proto_exists(new_name_buff)==EEXIST)
 
5480
                             new_db, new_name_buff, reg_ext, 0);
 
5481
        if (!access(new_name_buff, F_OK))
4445
5482
        {
4446
 
          /* Table will be closed by Session::executeCommand() */
 
5483
          /* Table will be closed in do_command() */
4447
5484
          my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
4448
5485
          goto err;
4449
5486
        }
4462
5499
    create_info->db_type= old_db_type;
4463
5500
  }
4464
5501
 
4465
 
  if (check_engine(session, new_name, create_info))
 
5502
  if (check_engine(thd, new_name, create_info))
4466
5503
    goto err;
4467
5504
  new_db_type= create_info->db_type;
4468
5505
 
4469
 
  if (new_db_type != old_db_type &&
 
5506
  if (new_db_type != old_db_type ||
4470
5507
      !table->file->can_switch_engines())
4471
5508
  {
4472
 
    assert(0);
4473
5509
    my_error(ER_ROW_IS_REFERENCED, MYF(0));
4474
5510
    goto err;
4475
5511
  }
4477
5513
  if (create_info->row_type == ROW_TYPE_NOT_USED)
4478
5514
    create_info->row_type= table->s->row_type;
4479
5515
 
4480
 
  if (old_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
4481
 
      new_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
 
5516
  if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
 
5517
      ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
4482
5518
  {
4483
5519
    my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4484
5520
    goto err;
4485
5521
  }
4486
5522
 
4487
 
  session->set_proc_info("setup");
 
5523
  thd_proc_info(thd, "setup");
4488
5524
  if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4489
5525
      !table->s->tmp_table) // no need to touch frm
4490
5526
  {
4494
5530
    case ENABLE:
4495
5531
      /*
4496
5532
        wait_while_table_is_used() ensures that table being altered is
4497
 
        opened only by this thread and that Table::TABLE_SHARE::version
4498
 
        of Table object corresponding to this table is 0.
 
5533
        opened only by this thread and that TABLE::TABLE_SHARE::version
 
5534
        of TABLE object corresponding to this table is 0.
4499
5535
        The latter guarantees that no DML statement will open this table
4500
 
        until ALTER Table finishes (i.e. until close_thread_tables())
 
5536
        until ALTER TABLE finishes (i.e. until close_thread_tables())
4501
5537
        while the fact that the table is still open gives us protection
4502
5538
        from concurrent DDL statements.
4503
5539
      */
4504
 
      pthread_mutex_lock(&LOCK_open);
4505
 
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4506
 
      pthread_mutex_unlock(&LOCK_open);
 
5540
      VOID(pthread_mutex_lock(&LOCK_open));
 
5541
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
5542
      VOID(pthread_mutex_unlock(&LOCK_open));
4507
5543
      error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4508
5544
      /* COND_refresh will be signaled in close_thread_tables() */
4509
5545
      break;
4510
5546
    case DISABLE:
4511
 
      pthread_mutex_lock(&LOCK_open);
4512
 
      wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4513
 
      pthread_mutex_unlock(&LOCK_open);
 
5547
      VOID(pthread_mutex_lock(&LOCK_open));
 
5548
      wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
5549
      VOID(pthread_mutex_unlock(&LOCK_open));
4514
5550
      error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4515
5551
      /* COND_refresh will be signaled in close_thread_tables() */
4516
5552
      break;
4522
5558
    if (error == HA_ERR_WRONG_COMMAND)
4523
5559
    {
4524
5560
      error= 0;
4525
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5561
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4526
5562
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4527
5563
                          table->alias);
4528
5564
    }
4529
5565
 
4530
 
    pthread_mutex_lock(&LOCK_open);
 
5566
    VOID(pthread_mutex_lock(&LOCK_open));
4531
5567
    /*
4532
5568
      Unlike to the above case close_cached_table() below will remove ALL
4533
 
      instances of Table from table cache (it will also remove table lock
 
5569
      instances of TABLE from table cache (it will also remove table lock
4534
5570
      held by this thread). So to make actual table renaming and writing
4535
5571
      to binlog atomic we have to put them into the same critical section
4536
5572
      protected by LOCK_open mutex. This also removes gap for races between
4539
5575
 
4540
5576
    if (!error && (new_name != table_name || new_db != db))
4541
5577
    {
4542
 
      session->set_proc_info("rename");
 
5578
      thd_proc_info(thd, "rename");
4543
5579
      /*
4544
5580
        Then do a 'simple' rename of the table. First we need to close all
4545
5581
        instances of 'source' table.
4546
5582
      */
4547
 
      close_cached_table(session, table);
 
5583
      close_cached_table(thd, table);
4548
5584
      /*
4549
5585
        Then, we want check once again that target table does not exist.
4550
5586
        Actually the order of these two steps does not matter since
4553
5589
        we don't take this name-lock and where this order really matters.
4554
5590
        TODO: Investigate if we need this access() check at all.
4555
5591
      */
4556
 
      if (table_proto_exists(new_name)==EEXIST)
 
5592
      if (!access(new_name_buff,F_OK))
4557
5593
      {
4558
5594
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
4559
5595
        error= -1;
4565
5601
          error= -1;
4566
5602
        else if (0)
4567
5603
      {
4568
 
          mysql_rename_table(old_db_type, new_db, new_alias, db,
4569
 
                             table_name, 0);
 
5604
          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
 
5605
                                  table_name, 0));
4570
5606
          error= -1;
4571
5607
      }
4572
5608
    }
4575
5611
    if (error == HA_ERR_WRONG_COMMAND)
4576
5612
  {
4577
5613
      error= 0;
4578
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
5614
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
4579
5615
                          ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
4580
5616
                          table->alias);
4581
5617
  }
4582
5618
 
4583
5619
    if (!error)
4584
5620
    {
4585
 
      write_bin_log(session, true, session->query, session->query_length);
4586
 
      session->my_ok();
 
5621
      write_bin_log(thd, true, thd->query, thd->query_length);
 
5622
      my_ok(thd);
4587
5623
  }
4588
5624
    else if (error > 0)
4589
5625
  {
4591
5627
      error= -1;
4592
5628
    }
4593
5629
    if (name_lock)
4594
 
      unlink_open_table(session, name_lock, false);
4595
 
    pthread_mutex_unlock(&LOCK_open);
 
5630
      unlink_open_table(thd, name_lock, false);
 
5631
    VOID(pthread_mutex_unlock(&LOCK_open));
4596
5632
    table_list->table= NULL;                    // For query cache
4597
5633
    return(error);
4598
5634
  }
4600
5636
  /* We have to do full alter table. */
4601
5637
 
4602
5638
    /*
4603
 
    If the old table had partitions and we are doing ALTER Table ...
 
5639
    If the old table had partitions and we are doing ALTER TABLE ...
4604
5640
    engine= <new_engine>, the new table must preserve the original
4605
5641
    partitioning. That means that the new engine is still the
4606
5642
    partitioning engine, not the engine specified in the parser.
4612
5648
  */
4613
5649
  new_db_type= create_info->db_type;
4614
5650
 
4615
 
  if (mysql_prepare_alter_table(session, table, create_info, alter_info))
 
5651
  if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
4616
5652
      goto err;
4617
5653
 
4618
 
  set_table_default_charset(session, create_info, db);
4619
 
 
4620
 
  if (session->variables.old_alter_table
 
5654
  set_table_default_charset(thd, create_info, db);
 
5655
 
 
5656
 
 
5657
  if (thd->variables.old_alter_table
4621
5658
      || (table->s->db_type() != create_info->db_type)
4622
5659
     )
4623
5660
  {
4624
5661
    if (alter_info->build_method == HA_BUILD_ONLINE)
4625
5662
    {
4626
 
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
 
5663
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4627
5664
      goto err;
4628
5665
    }
4629
5666
    alter_info->build_method= HA_BUILD_OFFLINE;
4631
5668
 
4632
5669
  if (alter_info->build_method != HA_BUILD_OFFLINE)
4633
5670
  {
4634
 
    Table *altered_table= 0;
 
5671
    TABLE *altered_table= 0;
4635
5672
    HA_ALTER_INFO ha_alter_info;
4636
5673
    HA_ALTER_FLAGS ha_alter_flags;
4637
 
    uint32_t table_changes= IS_EQUAL_YES;
 
5674
    uint table_changes= IS_EQUAL_YES;
4638
5675
    bool need_copy_table= true;
4639
5676
    /* Check how much the tables differ. */
4640
 
    if (compare_tables(session, table, alter_info,
 
5677
    if (compare_tables(thd, table, alter_info,
4641
5678
                       create_info, order_num,
4642
5679
                       &ha_alter_flags,
4643
5680
                       &ha_alter_info,
4658
5695
      can do the change on-line
4659
5696
    */
4660
5697
    if (new_name == table_name && new_db == db &&
4661
 
        ha_alter_flags.any())
 
5698
        ha_alter_flags.is_set())
4662
5699
    {
4663
 
      Alter_info tmp_alter_info(*alter_info, session->mem_root);
 
5700
      Alter_info tmp_alter_info(*alter_info, thd->mem_root);
4664
5701
 
4665
5702
      /*
4666
5703
        If no table rename,
4667
5704
        check if table can be altered on-line
4668
5705
      */
4669
 
      if (!(altered_table= create_altered_table(session,
 
5706
      if (!(altered_table= create_altered_table(thd,
4670
5707
                                                table,
4671
5708
                                                new_db,
4672
5709
                                                create_info,
4683
5720
        /*
4684
5721
          @todo: Currently we always acquire an exclusive name
4685
5722
          lock on the table metadata when performing fast or online
4686
 
          ALTER Table. In future we may consider this unnecessary,
 
5723
          ALTER TABLE. In future we may consider this unnecessary,
4687
5724
          and narrow the scope of the exclusive name lock to only
4688
5725
          cover manipulation with .frms. Storage engine API
4689
5726
          call check_if_supported_alter has provision for this
4694
5731
      case HA_ALTER_NOT_SUPPORTED:
4695
5732
        if (alter_info->build_method == HA_BUILD_ONLINE)
4696
5733
        {
4697
 
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4698
 
          close_temporary_table(session, altered_table, 1, 1);
 
5734
          my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
 
5735
          close_temporary_table(thd, altered_table, 1, 1);
4699
5736
          goto err;
4700
5737
        }
4701
5738
        need_copy_table= true;
4702
5739
        break;
4703
5740
      case HA_ALTER_ERROR:
4704
5741
      default:
4705
 
        close_temporary_table(session, altered_table, 1, 1);
 
5742
        close_temporary_table(thd, altered_table, 1, 1);
4706
5743
        goto err;
4707
5744
      }
4708
5745
 
4709
5746
    }
4710
 
    /* TODO need to check if changes can be handled as fast ALTER Table */
 
5747
    /* TODO need to check if changes can be handled as fast ALTER TABLE */
4711
5748
    if (!altered_table)
4712
5749
      need_copy_table= true;
4713
5750
 
4714
5751
    if (!need_copy_table)
4715
5752
    {
4716
 
      error= mysql_fast_or_online_alter_table(session,
 
5753
      error= mysql_fast_or_online_alter_table(thd,
4717
5754
                                              table,
4718
5755
                                              altered_table,
4719
5756
                                              create_info,
4720
5757
                                              &ha_alter_info,
4721
5758
                                              &ha_alter_flags,
4722
5759
                                              alter_info->keys_onoff);
4723
 
      if (session->lock)
 
5760
      if (thd->lock)
4724
5761
      {
4725
 
        mysql_unlock_tables(session, session->lock);
4726
 
        session->lock=0;
 
5762
        mysql_unlock_tables(thd, thd->lock);
 
5763
        thd->lock=0;
4727
5764
      }
4728
 
      close_temporary_table(session, altered_table, 1, 1);
 
5765
      close_temporary_table(thd, altered_table, 1, 1);
4729
5766
 
4730
5767
      if (error)
4731
5768
      {
4744
5781
    }
4745
5782
 
4746
5783
    if (altered_table)
4747
 
      close_temporary_table(session, altered_table, 1, 1);
 
5784
      close_temporary_table(thd, altered_table, 1, 1);
4748
5785
  }
4749
5786
 
4750
 
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
4751
 
           (unsigned long)current_pid, session->thread_id);
 
5787
  snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
 
5788
           current_pid, thd->thread_id);
4752
5789
  /* Safety fix for innodb */
4753
5790
  if (lower_case_table_names)
4754
5791
    my_casedn_str(files_charset_info, tmp_name);
4755
5792
 
4756
5793
 
4757
5794
  /* Create a temporary table with the new format */
4758
 
  if ((error= create_temporary_table(session, table, new_db, tmp_name,
4759
 
                                     create_info, alter_info,
 
5795
  if ((error= create_temporary_table(thd, table, new_db, tmp_name, 
 
5796
                                     create_info, alter_info, 
4760
5797
                                     !strcmp(db, new_db))))
4761
5798
  {
4762
5799
    goto err;
4765
5802
  /* Open the table so we need to copy the data to it. */
4766
5803
  if (table->s->tmp_table)
4767
5804
  {
4768
 
    TableList tbl;
4769
 
    memset(&tbl, 0, sizeof(tbl));
 
5805
    TABLE_LIST tbl;
 
5806
    bzero((void*) &tbl, sizeof(tbl));
4770
5807
    tbl.db= new_db;
4771
5808
    tbl.table_name= tbl.alias= tmp_name;
4772
 
    /* Table is in session->temporary_tables */
4773
 
    new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
 
5809
    /* Table is in thd->temporary_tables */
 
5810
    new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
 
5811
                          MYSQL_LOCK_IGNORE_FLUSH);
4774
5812
  }
4775
5813
  else
4776
5814
  {
4777
 
    char tmp_path[FN_REFLEN];
 
5815
    char path[FN_REFLEN];
4778
5816
    /* table is a normal table: Create temporary table in same directory */
4779
 
    build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, "",
 
5817
    build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4780
5818
                         FN_IS_TMP);
4781
5819
    /* Open our intermediate table */
4782
 
    new_table=open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
 
5820
    new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
4783
5821
  }
4784
5822
  if (!new_table)
4785
5823
    goto err1;
4786
5824
 
4787
5825
  /* Copy the data if necessary. */
4788
 
  session->count_cuted_fields= CHECK_FIELD_WARN;        // calc cuted fields
4789
 
  session->cuted_fields=0L;
4790
 
  session->set_proc_info("copy to tmp table");
 
5826
  thd->count_cuted_fields= CHECK_FIELD_WARN;    // calc cuted fields
 
5827
  thd->cuted_fields=0L;
 
5828
  thd_proc_info(thd, "copy to tmp table");
4791
5829
  copied=deleted=0;
4792
5830
  /*
4793
5831
    We do not copy data for MERGE tables. Only the children have data.
4795
5833
  */
4796
5834
  if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
4797
5835
  {
4798
 
    /* We don't want update TIMESTAMP fields during ALTER Table. */
 
5836
    /* We don't want update TIMESTAMP fields during ALTER TABLE. */
4799
5837
    new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
4800
5838
    new_table->next_number_field=new_table->found_next_number_field;
4801
5839
    error= copy_data_between_tables(table, new_table,
4806
5844
  }
4807
5845
  else
4808
5846
  {
4809
 
    pthread_mutex_lock(&LOCK_open);
4810
 
    wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4811
 
    pthread_mutex_unlock(&LOCK_open);
 
5847
    VOID(pthread_mutex_lock(&LOCK_open));
 
5848
    wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
 
5849
    VOID(pthread_mutex_unlock(&LOCK_open));
4812
5850
    alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4813
5851
                            alter_info->keys_onoff);
4814
 
    error= ha_autocommit_or_rollback(session, 0);
4815
 
    if (! session->endActiveTransaction())
 
5852
    error= ha_autocommit_or_rollback(thd, 0);
 
5853
    if (end_active_trans(thd))
4816
5854
      error= 1;
4817
5855
  }
4818
 
  /* We must not ignore bad input! */;
4819
 
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
5856
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
4820
5857
 
4821
5858
  if (table->s->tmp_table != NO_TMP_TABLE)
4822
5859
  {
4824
5861
    if (error)
4825
5862
      goto err1;
4826
5863
    /* Close lock if this is a transactional table */
4827
 
    if (session->lock)
 
5864
    if (thd->lock)
4828
5865
    {
4829
 
      mysql_unlock_tables(session, session->lock);
4830
 
      session->lock=0;
 
5866
      mysql_unlock_tables(thd, thd->lock);
 
5867
      thd->lock=0;
4831
5868
    }
4832
5869
    /* Remove link to old table and rename the new one */
4833
 
    close_temporary_table(session, table, 1, 1);
 
5870
    close_temporary_table(thd, table, 1, 1);
4834
5871
    /* Should pass the 'new_name' as we store table name in the cache */
4835
 
    if (rename_temporary_table(session, new_table, new_db, new_name))
 
5872
    if (rename_temporary_table(thd, new_table, new_db, new_name))
4836
5873
      goto err1;
 
5874
    /* We don't replicate alter table statement on temporary tables */
 
5875
    if (!thd->current_stmt_binlog_row_based)
 
5876
      write_bin_log(thd, true, thd->query, thd->query_length);
4837
5877
    goto end_temporary;
4838
5878
  }
4839
5879
 
4844
5884
      Note that MERGE tables do not have their children attached here.
4845
5885
    */
4846
5886
    intern_close_table(new_table);
4847
 
    free(new_table);
 
5887
    my_free(new_table,MYF(0));
4848
5888
  }
4849
 
  pthread_mutex_lock(&LOCK_open);
 
5889
  VOID(pthread_mutex_lock(&LOCK_open));
4850
5890
  if (error)
4851
5891
  {
4852
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4853
 
    pthread_mutex_unlock(&LOCK_open);
 
5892
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5893
    VOID(pthread_mutex_unlock(&LOCK_open));
4854
5894
    goto err;
4855
5895
  }
4856
5896
 
4861
5901
       with exclusive name-locks.
4862
5902
    3) Rename the old table to a temp name, rename the new one to the
4863
5903
       old name.
4864
 
    4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
 
5904
    4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
4865
5905
       we reopen new version of table.
4866
5906
    5) Write statement to the binary log.
4867
 
    6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
 
5907
    6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
4868
5908
       remove name-locks from list of open tables and table cache.
4869
5909
    7) If we are not not under LOCK TABLES we rely on close_thread_tables()
4870
5910
       call to remove name-locks from table cache and list of open table.
4871
5911
  */
4872
5912
 
4873
 
  session->set_proc_info("rename result table");
4874
 
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
4875
 
           (unsigned long)current_pid, session->thread_id);
 
5913
  thd_proc_info(thd, "rename result table");
 
5914
  snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
 
5915
           current_pid, thd->thread_id);
4876
5916
  if (lower_case_table_names)
4877
5917
    my_casedn_str(files_charset_info, old_name);
4878
5918
 
4879
 
  wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
4880
 
  close_data_files_and_morph_locks(session, db, table_name);
 
5919
  wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
 
5920
  close_data_files_and_morph_locks(thd, db, table_name);
4881
5921
 
4882
5922
  error=0;
4883
5923
  save_old_db_type= old_db_type;
4887
5927
    mysql_rename_table(), because we just juggle with the FRM and nothing
4888
5928
    more. If we have an intermediate table, then we notify the SE that
4889
5929
    it should become the actual table. Later, we will recycle the old table.
4890
 
    However, in case of ALTER Table RENAME there might be no intermediate
 
5930
    However, in case of ALTER TABLE RENAME there might be no intermediate
4891
5931
    table. This is when the old and new tables are compatible, according to
4892
5932
    compare_table(). Then, we need one additional call to
4893
5933
    mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
4899
5939
                         FN_TO_IS_TMP))
4900
5940
  {
4901
5941
    error=1;
4902
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
5942
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4903
5943
  }
4904
5944
  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
4905
5945
                              new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
4906
5946
  {
4907
5947
    /* Try to get everything back. */
4908
5948
    error=1;
4909
 
    quick_rm_table(new_db_type,new_db,new_alias, 0);
4910
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4911
 
    mysql_rename_table(old_db_type, db, old_name, db, alias,
4912
 
                       FN_FROM_IS_TMP);
 
5949
    VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
 
5950
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
 
5951
    VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
 
5952
                            FN_FROM_IS_TMP));
4913
5953
  }
4914
5954
 
4915
5955
  if (error)
4918
5958
    goto err_with_placeholders;
4919
5959
  }
4920
5960
 
4921
 
  quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
 
5961
  VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
4922
5962
 
4923
5963
end_online:
4924
 
  if (session->locked_tables && new_name == table_name && new_db == db)
 
5964
  if (thd->locked_tables && new_name == table_name && new_db == db)
4925
5965
  {
4926
 
    session->in_lock_tables= 1;
4927
 
    error= reopen_tables(session, 1, 1);
4928
 
    session->in_lock_tables= 0;
 
5966
    thd->in_lock_tables= 1;
 
5967
    error= reopen_tables(thd, 1, 1);
 
5968
    thd->in_lock_tables= 0;
4929
5969
    if (error)
4930
5970
      goto err_with_placeholders;
4931
5971
  }
4932
 
  pthread_mutex_unlock(&LOCK_open);
4933
 
 
4934
 
  session->set_proc_info("end");
4935
 
 
4936
 
  write_bin_log(session, true, session->query, session->query_length);
4937
 
 
4938
 
  if (old_db_type->check_flag(HTON_BIT_FLUSH_AFTER_RENAME))
 
5972
  VOID(pthread_mutex_unlock(&LOCK_open));
 
5973
 
 
5974
  thd_proc_info(thd, "end");
 
5975
 
 
5976
  ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
 
5977
                      thd->query, thd->query_length,
 
5978
                      db, table_name);
 
5979
 
 
5980
  assert(!(mysql_bin_log.is_open() &&
 
5981
                thd->current_stmt_binlog_row_based &&
 
5982
                (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
 
5983
  write_bin_log(thd, true, thd->query, thd->query_length);
 
5984
 
 
5985
  if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
4939
5986
  {
4940
5987
    /*
4941
5988
      For the alter table to be properly flushed to the logs, we
4942
5989
      have to open the new table.  If not, we get a problem on server
4943
5990
      shutdown. But we do not need to attach MERGE children.
4944
5991
    */
4945
 
    char table_path[FN_REFLEN];
4946
 
    Table *t_table;
4947
 
    build_table_filename(table_path, sizeof(table_path), new_db, table_name, "", 0);
4948
 
    t_table= open_temporary_table(session, table_path, new_db, tmp_name, false, OTM_OPEN);
 
5992
    char path[FN_REFLEN];
 
5993
    TABLE *t_table;
 
5994
    build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
 
5995
    t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
4949
5996
    if (t_table)
4950
5997
    {
4951
5998
      intern_close_table(t_table);
4952
 
      free(t_table);
 
5999
      my_free(t_table, MYF(0));
4953
6000
    }
4954
6001
    else
4955
 
      errmsg_printf(ERRMSG_LVL_WARN,
4956
 
                    _("Could not open table %s.%s after rename\n"),
4957
 
                    new_db,table_name);
 
6002
      sql_print_warning("Could not open table %s.%s after rename\n",
 
6003
                        new_db,table_name);
4958
6004
    ha_flush_logs(old_db_type);
4959
6005
  }
4960
6006
  table_list->table=0;                          // For query cache
4961
6007
 
4962
 
  if (session->locked_tables && (new_name != table_name || new_db != db))
 
6008
  if (thd->locked_tables && (new_name != table_name || new_db != db))
4963
6009
  {
4964
6010
    /*
4965
 
      If are we under LOCK TABLES and did ALTER Table with RENAME we need
 
6011
      If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
4966
6012
      to remove placeholders for the old table and for the target table
4967
6013
      from the list of open tables and table cache. If we are not under
4968
6014
      LOCK TABLES we can rely on close_thread_tables() doing this job.
4969
6015
    */
4970
6016
    pthread_mutex_lock(&LOCK_open);
4971
 
    unlink_open_table(session, table, false);
4972
 
    unlink_open_table(session, name_lock, false);
 
6017
    unlink_open_table(thd, table, false);
 
6018
    unlink_open_table(thd, name_lock, false);
4973
6019
    pthread_mutex_unlock(&LOCK_open);
4974
6020
  }
4975
6021
 
4976
6022
end_temporary:
4977
 
  /*
4978
 
   * Field::store() may have called my_error().  If this is 
4979
 
   * the case, we must not send an ok packet, since 
4980
 
   * Diagnostics_area::is_set() will fail an assert.
4981
 
   */
4982
 
  if (! session->is_error())
4983
 
  {
4984
 
    snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
4985
 
            (ulong) (copied + deleted), (ulong) deleted,
4986
 
            (ulong) session->cuted_fields);
4987
 
    session->my_ok(copied + deleted, 0L, tmp_name);
4988
 
    session->some_tables_deleted=0;
4989
 
    return false;
4990
 
  }
4991
 
  else
4992
 
  {
4993
 
    /* my_error() was called.  Return true (which means error...) */
4994
 
    return true;
4995
 
  }
 
6023
  snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
 
6024
           (ulong) (copied + deleted), (ulong) deleted,
 
6025
           (ulong) thd->cuted_fields);
 
6026
  my_ok(thd, copied + deleted, 0L, tmp_name);
 
6027
  thd->some_tables_deleted=0;
 
6028
  return(false);
4996
6029
 
4997
6030
err1:
4998
6031
  if (new_table)
4999
6032
  {
5000
6033
    /* close_temporary_table() frees the new_table pointer. */
5001
 
    close_temporary_table(session, new_table, 1, 1);
 
6034
    close_temporary_table(thd, new_table, 1, 1);
5002
6035
  }
5003
6036
  else
5004
 
    quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
 
6037
    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
5005
6038
 
5006
6039
err:
5007
6040
  /*
5010
6043
    the table to be altered isn't empty.
5011
6044
    Report error here.
5012
6045
  */
5013
 
  if (alter_info->error_if_not_empty && session->row_count)
 
6046
  if (alter_info->error_if_not_empty && thd->row_count)
5014
6047
  {
5015
6048
    const char *f_val= 0;
5016
 
    enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
 
6049
    enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
5017
6050
    switch (alter_info->datetime_field->sql_type)
5018
6051
    {
5019
 
      case DRIZZLE_TYPE_DATE:
 
6052
      case MYSQL_TYPE_NEWDATE:
5020
6053
        f_val= "0000-00-00";
5021
 
        t_type= DRIZZLE_TIMESTAMP_DATE;
 
6054
        t_type= MYSQL_TIMESTAMP_DATE;
5022
6055
        break;
5023
 
      case DRIZZLE_TYPE_DATETIME:
 
6056
      case MYSQL_TYPE_DATETIME:
5024
6057
        f_val= "0000-00-00 00:00:00";
5025
 
        t_type= DRIZZLE_TIMESTAMP_DATETIME;
 
6058
        t_type= MYSQL_TIMESTAMP_DATETIME;
5026
6059
        break;
5027
6060
      default:
5028
6061
        /* Shouldn't get here. */
5029
6062
        assert(0);
5030
6063
    }
5031
 
    bool save_abort_on_warning= session->abort_on_warning;
5032
 
    session->abort_on_warning= true;
5033
 
    make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
6064
    bool save_abort_on_warning= thd->abort_on_warning;
 
6065
    thd->abort_on_warning= true;
 
6066
    make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
5034
6067
                                 f_val, strlength(f_val), t_type,
5035
6068
                                 alter_info->datetime_field->field_name);
5036
 
    session->abort_on_warning= save_abort_on_warning;
 
6069
    thd->abort_on_warning= save_abort_on_warning;
5037
6070
  }
5038
6071
  if (name_lock)
5039
6072
  {
5040
6073
    pthread_mutex_lock(&LOCK_open);
5041
 
    unlink_open_table(session, name_lock, false);
 
6074
    unlink_open_table(thd, name_lock, false);
5042
6075
    pthread_mutex_unlock(&LOCK_open);
5043
6076
  }
5044
6077
  return(true);
5049
6082
    being altered. To be safe under LOCK TABLES we should remove placeholders
5050
6083
    from list of open tables list and table cache.
5051
6084
  */
5052
 
  unlink_open_table(session, table, false);
 
6085
  unlink_open_table(thd, table, false);
5053
6086
  if (name_lock)
5054
 
    unlink_open_table(session, name_lock, false);
5055
 
  pthread_mutex_unlock(&LOCK_open);
 
6087
    unlink_open_table(thd, name_lock, false);
 
6088
  VOID(pthread_mutex_unlock(&LOCK_open));
5056
6089
  return(true);
5057
6090
}
5058
6091
/* mysql_alter_table */
5059
6092
 
5060
6093
static int
5061
 
copy_data_between_tables(Table *from,Table *to,
 
6094
copy_data_between_tables(TABLE *from,TABLE *to,
5062
6095
                         List<Create_field> &create,
5063
6096
                         bool ignore,
5064
 
                         uint32_t order_num, order_st *order,
 
6097
                         uint order_num, ORDER *order,
5065
6098
                         ha_rows *copied,
5066
6099
                         ha_rows *deleted,
5067
6100
                         enum enum_enable_or_disable keys_onoff,
5070
6103
  int error;
5071
6104
  Copy_field *copy,*copy_end;
5072
6105
  ulong found_count,delete_count;
5073
 
  Session *session= current_session;
5074
 
  uint32_t length= 0;
 
6106
  THD *thd= current_thd;
 
6107
  uint length= 0;
5075
6108
  SORT_FIELD *sortorder;
5076
6109
  READ_RECORD info;
5077
 
  TableList   tables;
 
6110
  TABLE_LIST   tables;
5078
6111
  List<Item>   fields;
5079
6112
  List<Item>   all_fields;
5080
6113
  ha_rows examined_rows;
5081
6114
  bool auto_increment_field_copied= 0;
5082
6115
  ulong save_sql_mode;
5083
 
  uint64_t prev_insert_id;
 
6116
  ulonglong prev_insert_id;
5084
6117
 
5085
6118
  /*
5086
6119
    Turn off recovery logging since rollback of an alter table is to
5087
6120
    delete the new table so there is no need to log the changes to it.
5088
 
 
 
6121
    
5089
6122
    This needs to be done before external_lock
5090
6123
  */
5091
 
  error= ha_enable_transaction(session, false);
 
6124
  error= ha_enable_transaction(thd, false);
5092
6125
  if (error)
5093
6126
    return(-1);
5094
 
 
 
6127
  
5095
6128
  if (!(copy= new Copy_field[to->s->fields]))
5096
6129
    return(-1);                         /* purecov: inspected */
5097
6130
 
5098
 
  if (to->file->ha_external_lock(session, F_WRLCK))
 
6131
  if (to->file->ha_external_lock(thd, F_WRLCK))
5099
6132
    return(-1);
5100
6133
 
5101
6134
  /* We need external lock before we can disable/enable keys */
5102
6135
  alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5103
6136
 
5104
6137
  /* We can abort alter table for any table type */
5105
 
  session->abort_on_warning= !ignore;
 
6138
  thd->abort_on_warning= !ignore;
5106
6139
 
5107
6140
  from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5108
6141
  to->file->ha_start_bulk_insert(from->file->stats.records);
5109
6142
 
5110
 
  save_sql_mode= session->variables.sql_mode;
 
6143
  save_sql_mode= thd->variables.sql_mode;
5111
6144
 
5112
6145
  List_iterator<Create_field> it(create);
5113
6146
  Create_field *def;
5118
6151
    if (def->field)
5119
6152
    {
5120
6153
      if (*ptr == to->next_number_field)
 
6154
      {
5121
6155
        auto_increment_field_copied= true;
5122
 
 
 
6156
        /*
 
6157
          If we are going to copy contents of one auto_increment column to
 
6158
          another auto_increment column it is sensible to preserve zeroes.
 
6159
          This condition also covers case when we are don't actually alter
 
6160
          auto_increment column.
 
6161
        */
 
6162
        if (def->field == from->found_next_number_field)
 
6163
          thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
 
6164
      }
5123
6165
      (copy_end++)->set(*ptr,def->field,0);
5124
6166
    }
5125
6167
 
5131
6173
  {
5132
6174
    if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5133
6175
    {
5134
 
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
5135
 
      snprintf(warn_buff, sizeof(warn_buff),
5136
 
               _("order_st BY ignored because there is a user-defined clustered "
5137
 
                 "index in the table '%-.192s'"),
5138
 
               from->s->table_name.str);
5139
 
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
6176
      char warn_buff[MYSQL_ERRMSG_SIZE];
 
6177
      snprintf(warn_buff, sizeof(warn_buff), 
 
6178
               "ORDER BY ignored as there is a user-defined clustered index"
 
6179
               " in the table '%-.192s'", from->s->table_name.str);
 
6180
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5140
6181
                   warn_buff);
5141
6182
    }
5142
6183
    else
5143
6184
    {
5144
 
      from->sort.io_cache= new IO_CACHE;
5145
 
      memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
5146
 
 
5147
 
      memset(&tables, 0, sizeof(tables));
 
6185
      from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
 
6186
                                                MYF(MY_FAE | MY_ZEROFILL));
 
6187
      bzero((char *) &tables, sizeof(tables));
5148
6188
      tables.table= from;
5149
6189
      tables.alias= tables.table_name= from->s->table_name.str;
5150
6190
      tables.db= from->s->db.str;
5151
6191
      error= 1;
5152
6192
 
5153
 
      if (session->lex->select_lex.setup_ref_array(session, order_num) ||
5154
 
          setup_order(session, session->lex->select_lex.ref_pointer_array,
 
6193
      if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
 
6194
          setup_order(thd, thd->lex->select_lex.ref_pointer_array,
5155
6195
                      &tables, fields, all_fields, order) ||
5156
6196
          !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5157
 
          (from->sort.found_records= filesort(session, from, sortorder, length,
 
6197
          (from->sort.found_records= filesort(thd, from, sortorder, length,
5158
6198
                                              (SQL_SELECT *) 0, HA_POS_ERROR,
5159
6199
                                              1, &examined_rows)) ==
5160
6200
          HA_POS_ERROR)
5164
6204
 
5165
6205
  /* Tell handler that we have values for all columns in the to table */
5166
6206
  to->use_all_columns();
5167
 
  init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
 
6207
  init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
5168
6208
  if (ignore)
5169
6209
    to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5170
 
  session->row_count= 0;
 
6210
  thd->row_count= 0;
5171
6211
  restore_record(to, s->default_values);        // Create empty record
5172
6212
  while (!(error=info.read_record(&info)))
5173
6213
  {
5174
 
    if (session->killed)
 
6214
    if (thd->killed)
5175
6215
    {
5176
 
      session->send_kill_message();
 
6216
      thd->send_kill_message();
5177
6217
      error= 1;
5178
6218
      break;
5179
6219
    }
5180
 
    session->row_count++;
 
6220
    thd->row_count++;
5181
6221
    /* Return error if source table isn't empty. */
5182
6222
    if (error_if_not_empty)
5183
6223
    {
5191
6231
      else
5192
6232
        to->next_number_field->reset();
5193
6233
    }
5194
 
 
 
6234
    
5195
6235
    for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
5196
6236
    {
5197
6237
      copy_ptr->do_copy(copy_ptr);
5198
6238
    }
5199
6239
    prev_insert_id= to->file->next_insert_id;
5200
 
    update_virtual_fields_marked_for_write(to, false);
5201
6240
    error=to->file->ha_write_row(to->record[0]);
5202
6241
    to->auto_increment_field_not_null= false;
5203
6242
    if (error)
5207
6246
      {
5208
6247
         if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
5209
6248
         {
5210
 
           uint32_t key_nr= to->file->get_dup_key(error);
 
6249
           uint key_nr= to->file->get_dup_key(error);
5211
6250
           if ((int) key_nr >= 0)
5212
6251
           {
5213
6252
             const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
5240
6279
  }
5241
6280
  to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
5242
6281
 
5243
 
  if (ha_enable_transaction(session, true))
 
6282
  if (ha_enable_transaction(thd, true))
5244
6283
  {
5245
6284
    error= 1;
5246
6285
    goto err;
5250
6289
    Ensure that the new table is saved properly to disk so that we
5251
6290
    can do a rename
5252
6291
  */
5253
 
  if (ha_autocommit_or_rollback(session, 0))
 
6292
  if (ha_autocommit_or_rollback(thd, 0))
5254
6293
    error=1;
5255
 
  if (! session->endActiveTransaction())
 
6294
  if (end_active_trans(thd))
5256
6295
    error=1;
5257
6296
 
5258
6297
 err:
5259
 
  session->variables.sql_mode= save_sql_mode;
5260
 
  session->abort_on_warning= 0;
 
6298
  thd->variables.sql_mode= save_sql_mode;
 
6299
  thd->abort_on_warning= 0;
5261
6300
  free_io_cache(from);
5262
6301
  *copied= found_count;
5263
6302
  *deleted=delete_count;
5264
6303
  to->file->ha_release_auto_increment();
5265
 
  if (to->file->ha_external_lock(session,F_UNLCK))
 
6304
  if (to->file->ha_external_lock(thd,F_UNLCK))
5266
6305
    error=1;
5267
6306
  return(error > 0 ? -1 : 0);
5268
6307
}
5273
6312
 
5274
6313
  SYNOPSIS
5275
6314
    mysql_recreate_table()
5276
 
    session                     Thread handler
 
6315
    thd                 Thread handler
5277
6316
    tables              Tables to recreate
5278
6317
 
5279
6318
 RETURN
5280
6319
    Like mysql_alter_table().
5281
6320
*/
5282
 
bool mysql_recreate_table(Session *session, TableList *table_list)
 
6321
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
5283
6322
{
5284
6323
  HA_CREATE_INFO create_info;
5285
6324
  Alter_info alter_info;
5291
6330
  */
5292
6331
  table_list->table= NULL;
5293
6332
 
5294
 
  memset(&create_info, 0, sizeof(create_info));
 
6333
  bzero((char*) &create_info, sizeof(create_info));
5295
6334
  create_info.row_type=ROW_TYPE_NOT_USED;
5296
6335
  create_info.default_table_charset=default_charset_info;
5297
6336
  /* Force alter table to recreate table */
5298
6337
  alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5299
 
  return(mysql_alter_table(session, NULL, NULL, &create_info,
 
6338
  return(mysql_alter_table(thd, NullS, NullS, &create_info,
5300
6339
                                table_list, &alter_info, 0,
5301
 
                                (order_st *) 0, 0));
 
6340
                                (ORDER *) 0, 0));
5302
6341
}
5303
6342
 
5304
6343
 
5305
 
bool mysql_checksum_table(Session *session, TableList *tables,
 
6344
bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
5306
6345
                          HA_CHECK_OPT *check_opt)
5307
6346
{
5308
 
  TableList *table;
 
6347
  TABLE_LIST *table;
5309
6348
  List<Item> field_list;
5310
6349
  Item *item;
5311
 
  Protocol *protocol= session->protocol;
 
6350
  Protocol *protocol= thd->protocol;
5312
6351
 
5313
6352
  field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5314
6353
  item->maybe_null= 1;
5315
 
  field_list.push_back(item= new Item_int("Checksum", (int64_t) 1,
 
6354
  field_list.push_back(item= new Item_int("Checksum", (longlong) 1,
5316
6355
                                          MY_INT64_NUM_DECIMAL_DIGITS));
5317
6356
  item->maybe_null= 1;
5318
 
  if (protocol->sendFields(&field_list,
5319
 
                           Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
6357
  if (protocol->send_fields(&field_list,
 
6358
                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
5320
6359
    return(true);
5321
6360
 
5322
6361
  /* Open one table after the other to keep lock time as short as possible. */
5323
6362
  for (table= tables; table; table= table->next_local)
5324
6363
  {
5325
6364
    char table_name[NAME_LEN*2+2];
5326
 
    Table *t;
5327
 
 
5328
 
    sprintf(table_name,"%s.%s",table->db,table->table_name);
5329
 
 
5330
 
    t= table->table= open_n_lock_single_table(session, table, TL_READ);
5331
 
    session->clear_error();                     // these errors shouldn't get client
5332
 
 
5333
 
    protocol->prepareForResend();
 
6365
    TABLE *t;
 
6366
 
 
6367
    strxmov(table_name, table->db ,".", table->table_name, NullS);
 
6368
 
 
6369
    t= table->table= open_n_lock_single_table(thd, table, TL_READ);
 
6370
    thd->clear_error();                 // these errors shouldn't get client
 
6371
 
 
6372
    protocol->prepare_for_resend();
5334
6373
    protocol->store(table_name, system_charset_info);
5335
6374
 
5336
6375
    if (!t)
5337
6376
    {
5338
6377
      /* Table didn't exist */
5339
 
      protocol->store();
5340
 
      session->clear_error();
 
6378
      protocol->store_null();
 
6379
      thd->clear_error();
5341
6380
    }
5342
6381
    else
5343
6382
    {
5344
6383
      if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
5345
6384
          !(check_opt->flags & T_EXTEND))
5346
 
        protocol->store((uint64_t)t->file->checksum());
 
6385
        protocol->store((ulonglong)t->file->checksum());
5347
6386
      else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
5348
6387
               (check_opt->flags & T_QUICK))
5349
 
        protocol->store();
 
6388
        protocol->store_null();
5350
6389
      else
5351
6390
      {
5352
6391
        /* calculating table's checksum */
5353
6392
        ha_checksum crc= 0;
5354
 
        unsigned char null_mask=256 -  (1 << t->s->last_null_bit_pos);
 
6393
        uchar null_mask=256 -  (1 << t->s->last_null_bit_pos);
5355
6394
 
5356
6395
        t->use_all_columns();
5357
6396
 
5358
6397
        if (t->file->ha_rnd_init(1))
5359
 
          protocol->store();
 
6398
          protocol->store_null();
5360
6399
        else
5361
6400
        {
5362
6401
          for (;;)
5379
6418
              row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
5380
6419
            }
5381
6420
 
5382
 
            for (uint32_t i= 0; i < t->s->fields; i++ )
 
6421
            for (uint i= 0; i < t->s->fields; i++ )
5383
6422
            {
5384
6423
              Field *f= t->field[i];
5385
 
              if ((f->type() == DRIZZLE_TYPE_BLOB) ||
5386
 
                  (f->type() == DRIZZLE_TYPE_VARCHAR))
 
6424
              if ((f->type() == MYSQL_TYPE_BLOB) ||
 
6425
                  (f->type() == MYSQL_TYPE_VARCHAR))
5387
6426
              {
5388
6427
                String tmp;
5389
6428
                f->val_str(&tmp);
5390
 
                row_crc= my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
 
6429
                row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
5391
6430
              }
5392
6431
              else
5393
6432
                row_crc= my_checksum(row_crc, f->ptr,
5396
6435
 
5397
6436
            crc+= row_crc;
5398
6437
          }
5399
 
          protocol->store((uint64_t)crc);
 
6438
          protocol->store((ulonglong)crc);
5400
6439
          t->file->ha_rnd_end();
5401
6440
        }
5402
6441
      }
5403
 
      session->clear_error();
5404
 
      close_thread_tables(session);
 
6442
      thd->clear_error();
 
6443
      close_thread_tables(thd);
5405
6444
      table->table=0;                           // For query cache
5406
6445
    }
5407
6446
    if (protocol->write())
5408
6447
      goto err;
5409
6448
  }
5410
6449
 
5411
 
  session->my_eof();
 
6450
  my_eof(thd);
5412
6451
  return(false);
5413
6452
 
5414
6453
 err:
5415
 
  close_thread_tables(session);                 // Shouldn't be needed
 
6454
  close_thread_tables(thd);                     // Shouldn't be needed
5416
6455
  if (table)
5417
6456
    table->table=0;
5418
6457
  return(true);
5419
6458
}
5420
6459
 
5421
 
static bool check_engine(Session *session, const char *table_name,
 
6460
static bool check_engine(THD *thd, const char *table_name,
5422
6461
                         HA_CREATE_INFO *create_info)
5423
6462
{
5424
 
  StorageEngine **new_engine= &create_info->db_type;
5425
 
  StorageEngine *req_engine= *new_engine;
5426
 
  if (!req_engine->is_enabled())
5427
 
  {
5428
 
    string engine_name= req_engine->getName();
5429
 
    my_error(ER_FEATURE_DISABLED,MYF(0),
5430
 
             engine_name.c_str(), engine_name.c_str());
5431
 
             
 
6463
  handlerton **new_engine= &create_info->db_type;
 
6464
  handlerton *req_engine= *new_engine;
 
6465
  bool no_substitution= 1;
 
6466
  if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
 
6467
                                  no_substitution, 1)))
5432
6468
    return true;
5433
 
  }
5434
6469
 
5435
6470
  if (req_engine && req_engine != *new_engine)
5436
6471
  {
5437
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
6472
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
5438
6473
                       ER_WARN_USING_OTHER_HANDLER,
5439
6474
                       ER(ER_WARN_USING_OTHER_HANDLER),
5440
 
                       ha_resolve_storage_engine_name(*new_engine).c_str(),
 
6475
                       ha_resolve_storage_engine_name(*new_engine),
5441
6476
                       table_name);
5442
6477
  }
5443
6478
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5444
 
      (*new_engine)->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED))
 
6479
      ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
5445
6480
  {
5446
6481
    if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5447
6482
    {
5448
6483
      my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
5449
 
               ha_resolve_storage_engine_name(*new_engine).c_str(),
5450
 
               "TEMPORARY");
 
6484
               ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
5451
6485
      *new_engine= 0;
5452
6486
      return true;
5453
6487
    }
5454
 
    *new_engine= myisam_engine;
 
6488
    *new_engine= myisam_hton;
5455
6489
  }
5456
6490
  return false;
5457
6491
}