18
18
#include <drizzled/server_includes.h>
19
19
#include <storage/myisam/myisam.h>
20
#include <drizzled/sql_show.h>
21
#include <drizzled/drizzled_error_messages.h>
22
#include <libdrizzle/gettext.h>
20
#include <drizzled/show.h>
21
#include <drizzled/error.h>
22
#include <drizzled/gettext.h>
23
#include <drizzled/data_home.h>
24
#include <drizzled/sql_parse.h>
25
#include <mysys/hash.h>
26
#include <drizzled/sql_lex.h>
27
#include <drizzled/session.h>
28
#include <drizzled/sql_base.h>
29
#include <drizzled/db.h>
30
#include <drizzled/lock.h>
31
#include <drizzled/unireg.h>
32
#include <drizzled/item/int.h>
33
#include <drizzled/item/empty_string.h>
34
#include <drizzled/transaction_services.h>
38
extern drizzled::TransactionServices transaction_services;
39
extern HASH lock_db_cache;
24
41
int creating_table= 0; // How many mysql_create_table are running
26
const char *primary_key_name="PRIMARY";
44
bool is_primary_key(KEY *key_info)
46
static const char * primary_key_name="PRIMARY";
47
return (strcmp(key_info->name, primary_key_name)==0);
50
const char* is_primary_key_name(const char* key_name)
52
static const char * primary_key_name="PRIMARY";
53
if (strcmp(key_name, primary_key_name)==0)
28
59
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
60
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
34
65
enum enum_enable_or_disable keys_onoff,
35
66
bool error_if_not_empty);
37
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
38
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
68
static bool prepare_blob_field(Session *session, Create_field *sql_field);
69
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
71
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
41
72
Alter_info *alter_info,
43
74
uint32_t *db_options,
44
75
handler *file, KEY **key_info_buffer,
45
76
uint32_t *key_count, int select_field_count);
47
mysql_prepare_alter_table(THD *thd, Table *table,
78
mysql_prepare_alter_table(Session *session, Table *table,
48
79
HA_CREATE_INFO *create_info,
49
80
Alter_info *alter_info);
82
static void set_table_default_charset(Session *session,
83
HA_CREATE_INFO *create_info, char *db)
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.
90
if (!create_info->default_table_charset)
92
HA_CREATE_INFO db_info;
94
load_db_opt_by_name(session, db, &db_info);
96
create_info->default_table_charset= db_info.default_table_charset;
52
101
Translate a file name to a table name (WL #1324).
150
194
build_tmptable_filename() for them.
197
path length on success, 0 on failure
156
200
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
157
201
const char *table_name, const char *ext, uint32_t flags)
159
204
char dbbuff[FN_REFLEN];
160
205
char tbbuff[FN_REFLEN];
206
int rootdir_len= strlen(FN_ROOTDIR);
162
208
if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
209
strncpy(tbbuff, table_name, sizeof(tbbuff));
165
211
tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
167
213
tablename_to_filename(db, dbbuff, sizeof(dbbuff));
169
char *end = buff + bufflen;
170
/* Don't add FN_ROOTDIR if mysql_data_home already includes it */
171
char *pos = my_stpncpy(buff, mysql_data_home, bufflen);
172
int rootdir_len= strlen(FN_ROOTDIR);
173
if (pos - rootdir_len >= buff &&
174
memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
175
pos= my_stpncpy(pos, FN_ROOTDIR, end - pos);
176
pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NULL);
214
table_path= drizzle_data_home;
215
int without_rootdir= table_path.length()-rootdir_len;
217
/* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
218
if (without_rootdir >= 0)
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);
225
table_path.append(dbbuff);
226
table_path.append(FN_ROOTDIR);
177
227
#ifdef USE_SYMDIR
178
unpack_dirname(buff, buff);
181
pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
230
table_path.append(tbbuff);
231
table_path.append(ext);
233
if (bufflen < table_path.length())
236
strcpy(buff, table_path.c_str());
237
return table_path.length();
188
Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
242
Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
191
245
build_tmptable_filename()
192
thd The thread handle.
246
session The thread handle.
193
247
buff Where to write result in my_charset_filename.
194
248
bufflen buff size
198
252
Uses current_pid, thread_id, and tmp_table counter to create
199
a file name in mysql_tmpdir.
253
a file name in drizzle_tmpdir.
256
path length on success, 0 on failure
205
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
259
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
262
ostringstream path_str, post_tmpdir_str;
208
char *p= my_stpncpy(buff, mysql_tmpdir, bufflen);
209
snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
210
tmp_file_prefix, current_pid,
211
thd->thread_id, thd->tmp_table++, reg_ext);
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();
213
270
if (lower_case_table_names)
215
/* Convert all except tmpdir to lower case */
216
my_casedn_str(files_charset_info, p);
219
uint32_t length= unpack_filename(buff, buff);
271
transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
275
if (bufflen < path_str.str().length())
278
length= unpack_filename(buff, path_str.str().c_str());
286
session Thread object
227
287
clear_error is clear_error to be called
228
288
query Query to log
229
289
query_length Length of query
338
392
-1 Thread was killed
341
int mysql_rm_table_part2(THD *thd, TableList *tables, bool if_exists,
342
bool drop_temporary, bool drop_view,
395
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
396
bool drop_temporary, bool dont_log_query)
345
398
TableList *table;
346
399
char path[FN_REFLEN], *alias;
347
uint32_t path_length;
400
uint32_t path_length= 0;
348
401
String wrong_tables;
350
403
int non_temp_tables_count= 0;
351
404
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
352
405
String built_query;
354
if (thd->current_stmt_binlog_row_based && !dont_log_query)
356
409
built_query.set_charset(system_charset_info);
378
429
table->db_type= share->db_type();
381
if (!drop_temporary && lock_table_names_exclusively(thd, tables))
432
if (!drop_temporary && lock_table_names_exclusively(session, tables))
383
434
pthread_mutex_unlock(&LOCK_open);
387
438
/* Don't give warnings for not found errors, as we already generate notes */
388
thd->no_warnings_for_error= 1;
439
session->no_warnings_for_error= 1;
390
441
for (table= tables; table; table= table->next_local)
392
443
char *db=table->db;
393
handlerton *table_type;
394
enum legacy_db_type frm_db_type;
397
error= drop_temporary_table(thd, table);
444
StorageEngine *table_type;
446
error= drop_temporary_table(session, table);
438
486
if (!drop_temporary)
440
488
Table *locked_table;
441
abort_locked_tables(thd, db, table->table_name);
442
remove_table_from_cache(thd, db, table->table_name,
489
abort_locked_tables(session, db, table->table_name);
490
remove_table_from_cache(session, db, table->table_name,
443
491
RTFC_WAIT_OTHER_THREAD_FLAG |
444
492
RTFC_CHECK_KILLED_FLAG);
446
494
If the table was used in lock tables, remember it so that
447
495
unlock_table_names can free it
449
if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
497
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
450
498
table->table= locked_table;
455
503
goto err_with_placeholders;
457
505
alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
458
506
/* remove .frm file and engine files */
459
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
507
path_length= build_table_filename(path, sizeof(path), db, alias, "",
460
508
table->internal_tmp_table ?
463
511
if (drop_temporary ||
464
((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
465
(!drop_view && mysql_frm_type(thd, path, &frm_db_type) != true)))
512
((table_type == NULL && (table_proto_exists(path)!=EEXIST))))
467
514
// Table was not found on disk and table can't be created from engine
469
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
516
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
470
517
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
471
518
table->table_name);
478
if (table_type == NULL)
480
mysql_frm_type(thd, path, &frm_db_type);
481
table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
483
// Remove extension for delete
484
*(end= path + path_length - reg_ext_length)= '\0';
485
error= ha_delete_table(thd, table_type, path, db, table->table_name,
524
error= ha_delete_table(session, path, db, table->table_name,
486
525
!dont_log_query);
487
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
488
(if_exists || table_type == NULL))
526
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
530
session->clear_error();
493
532
if (error == HA_ERR_ROW_IS_REFERENCED)
607
bool quick_rm_table(handlerton *base,const char *db,
643
bool quick_rm_table(StorageEngine *,const char *db,
608
644
const char *table_name, uint32_t flags)
610
646
char path[FN_REFLEN];
613
uint32_t path_length= build_table_filename(path, sizeof(path),
614
db, table_name, reg_ext, flags);
615
if (my_delete(path,MYF(0)))
616
error= 1; /* purecov: inspected */
617
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
618
return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
649
build_table_filename(path, sizeof(path), db, table_name, "", flags);
651
error= delete_table_proto_file(path);
653
return(ha_delete_table(current_session, path, db, table_name, 0) ||
1571
Set table default charset, if not set
1574
set_table_default_charset()
1575
create_info Table create information
1578
If the table character set was not given explicitely,
1579
let's fetch the database default character set and
1580
apply it to the table.
1583
static void set_table_default_charset(THD *thd,
1584
HA_CREATE_INFO *create_info, char *db)
1587
If the table character set was not given explicitly,
1588
let's fetch the database default character set and
1589
apply it to the table.
1591
if (!create_info->default_table_charset)
1593
HA_CREATE_INFO db_info;
1595
load_db_opt_by_name(thd, db, &db_info);
1597
create_info->default_table_charset= db_info.default_table_charset;
1603
1636
Extend long VARCHAR fields to blob & prepare field if it's a blob
1642
Preparation of Create_field for SP function return values.
1643
Based on code used in the inner loop of mysql_prepare_create_table()
1647
sp_prepare_create_field()
1649
sql_field Field to prepare
1652
Prepares the field structures for field creation.
1656
void sp_prepare_create_field(THD *thd, Create_field *sql_field)
1658
if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
1660
uint32_t field_length, dummy;
1661
/* DRIZZLE_TYPE_ENUM */
1663
calculate_interval_lengths(sql_field->charset,
1664
sql_field->interval,
1665
&field_length, &dummy);
1666
sql_field->length= field_length;
1668
set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
1671
sql_field->create_length_to_internal_length();
1672
assert(sql_field->def == 0);
1673
/* Can't go wrong as sql_field->def is not defined */
1674
(void) prepare_blob_field(thd, sql_field);
1682
1678
mysql_create_table_no_lock()
1679
session Thread object
1685
1681
table_name Table name
1686
1682
create_info Create information (like MAX_ROWS)
1732
if (check_engine(thd, table_name, create_info))
1729
if (check_engine(session, table_name, create_info))
1734
1731
db_options= create_info->table_options;
1735
1732
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1736
1733
db_options|=HA_OPTION_PACK_RECORD;
1737
1734
alias= table_case_name(create_info, table_name);
1738
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
1735
if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1739
1736
create_info->db_type)))
1741
1738
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1745
set_table_default_charset(thd, create_info, (char*) db);
1742
set_table_default_charset(session, create_info, (char*) db);
1747
if (mysql_prepare_create_table(thd, create_info, alter_info,
1744
if (mysql_prepare_create_table(session, create_info, alter_info,
1748
1745
internal_tmp_table,
1749
1746
&db_options, file,
1750
1747
&key_info_buffer, &key_count,
1770
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
1767
path_length= build_table_filename(path, sizeof(path), db, alias, "",
1771
1768
internal_tmp_table ? FN_IS_TMP : 0);
1774
1771
/* Check if table already exists */
1775
1772
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1776
find_temporary_table(thd, db, table_name))
1773
find_temporary_table(session, db, table_name))
1778
1775
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1780
1777
create_info->table_existed= 1; // Mark that table existed
1781
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1778
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1782
1779
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1864
1861
#endif /* HAVE_READLINK */
1866
1863
if (create_info->data_file_name)
1867
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1864
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1868
1865
"DATA DIRECTORY option ignored");
1869
1866
if (create_info->index_file_name)
1870
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1867
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1871
1868
"INDEX DIRECTORY option ignored");
1872
1869
create_info->data_file_name= create_info->index_file_name= 0;
1874
1871
create_info->table_options=db_options;
1876
path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1877
if (rea_create_table(thd, path, db, table_name,
1873
if (rea_create_table(session, path, db, table_name,
1878
1874
create_info, alter_info->create_list,
1879
key_count, key_info_buffer, file))
1875
key_count, key_info_buffer, file, false))
1880
1876
goto unlock_and_end;
1882
1878
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1884
1880
/* Open table and put in temporary table list */
1885
if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
1881
if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1887
(void) rm_temporary_table(create_info->db_type, path, false);
1883
(void) rm_temporary_table(create_info->db_type, path);
1888
1884
goto unlock_and_end;
1890
thd->thread_specific_used= true;
1886
session->thread_specific_used= true;
1898
1894
Otherwise, the statement shall be binlogged.
1900
1896
if (!internal_tmp_table &&
1901
(!thd->current_stmt_binlog_row_based ||
1902
(thd->current_stmt_binlog_row_based &&
1903
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1904
write_bin_log(thd, true, thd->query, thd->query_length);
1897
((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1898
write_bin_log(session, true, session->query, session->query_length);
1906
1900
unlock_and_end:
1907
pthread_mutex_unlock(&LOCK_open);
1902
pthread_mutex_unlock(&LOCK_open);
1910
thd_proc_info(thd, "After create");
1905
session->set_proc_info("After create");
1916
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1911
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1917
1912
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1919
1914
create_info->table_existed= 1; // Mark that table existed
2090
2087
if (lower_case_table_names == 2 && file &&
2091
2088
!(file->ha_table_flags() & HA_FILE_BASED))
2093
my_stpcpy(tmp_name, old_name);
2090
strcpy(tmp_name, old_name);
2094
2091
my_casedn_str(files_charset_info, tmp_name);
2095
2092
build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2096
2093
flags & FN_FROM_IS_TMP);
2097
2094
from_base= lc_from;
2099
my_stpcpy(tmp_name, new_name);
2096
strcpy(tmp_name, new_name);
2100
2097
my_casedn_str(files_charset_info, tmp_name);
2101
2098
build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2102
2099
flags & FN_TO_IS_TMP);
2174
2171
Win32 clients must also have a WRITE LOCK on the table !
2177
void close_cached_table(THD *thd, Table *table)
2174
void close_cached_table(Session *session, Table *table)
2180
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
2177
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2181
2178
/* Close lock if this is not got with LOCK TABLES */
2184
mysql_unlock_tables(thd, thd->lock);
2185
thd->lock=0; // Start locked threads
2181
mysql_unlock_tables(session, session->lock);
2182
session->lock=0; // Start locked threads
2187
2184
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
2188
unlink_open_table(thd, table, true);
2185
unlink_open_table(session, table, true);
2190
2187
/* When lock on LOCK_open is freed other threads can continue */
2191
2188
broadcast_refresh();
2195
static int send_check_errmsg(THD *thd, TableList* table,
2192
static int send_check_errmsg(Session *session, TableList* table,
2196
2193
const char* operator_name, const char* errmsg)
2199
Protocol *protocol= thd->protocol;
2200
protocol->prepare_for_resend();
2196
Protocol *protocol= session->protocol;
2197
protocol->prepareForResend();
2201
2198
protocol->store(table->alias, system_charset_info);
2202
2199
protocol->store((char*) operator_name, system_charset_info);
2203
2200
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2204
2201
protocol->store(errmsg, system_charset_info);
2202
session->clear_error();
2206
2203
if (protocol->write())
2212
static int prepare_for_repair(THD *thd, TableList *table_list,
2209
static int prepare_for_repair(Session *session, TableList *table_list,
2213
2210
HA_CHECK_OPT *check_opt)
2227
2224
char key[MAX_DBKEY_LENGTH];
2228
2225
uint32_t key_length;
2230
key_length= create_table_def_key(thd, key, table_list, 0);
2227
key_length= create_table_def_key(session, key, table_list, 0);
2231
2228
pthread_mutex_lock(&LOCK_open);
2232
if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
2229
if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2235
2232
pthread_mutex_unlock(&LOCK_open);
2236
2233
return(0); // Can't open frm file
2239
if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2236
if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2241
2238
release_table_share(share, RELEASE_NORMAL);
2242
2239
pthread_mutex_unlock(&LOCK_open);
2270
2267
Check if this is a table type that stores index and data separately,
2271
2268
like ISAM or MyISAM. We assume fixed order of engine file name
2272
2269
extentions array. First element of engine file name extentions array
2273
is meta/index file extention. Second element - data file extention.
2270
is meta/index file extention. Second element - data file extention.
2275
2272
ext= table->file->bas_ext();
2276
2273
if (!ext[0] || !ext[1])
2277
2274
goto end; // No data file
2279
2276
// Name of data file
2280
strxmov(from, table->s->normalized_path.str, ext[1], NULL);
2277
sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2281
2278
if (stat(from, &stat_info))
2282
2279
goto end; // Can't use USE_FRM flag
2284
snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2285
from, current_pid, thd->thread_id);
2281
snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
2282
from, (unsigned long)current_pid, session->thread_id);
2287
2284
/* If we could open the table, close it */
2288
2285
if (table_list->table)
2290
2287
pthread_mutex_lock(&LOCK_open);
2291
close_cached_table(thd, table);
2288
close_cached_table(session, table);
2292
2289
pthread_mutex_unlock(&LOCK_open);
2294
if (lock_and_wait_for_table_name(thd,table_list))
2291
if (lock_and_wait_for_table_name(session,table_list))
2299
2296
if (my_rename(from, tmp, MYF(MY_WME)))
2301
2298
pthread_mutex_lock(&LOCK_open);
2302
unlock_table_name(thd, table_list);
2299
unlock_table_name(session, table_list);
2303
2300
pthread_mutex_unlock(&LOCK_open);
2304
error= send_check_errmsg(thd, table_list, "repair",
2301
error= send_check_errmsg(session, table_list, "repair",
2305
2302
"Failed renaming data file");
2308
if (mysql_truncate(thd, table_list, 1))
2305
if (mysql_truncate(session, table_list, 1))
2310
2307
pthread_mutex_lock(&LOCK_open);
2311
unlock_table_name(thd, table_list);
2308
unlock_table_name(session, table_list);
2312
2309
pthread_mutex_unlock(&LOCK_open);
2313
error= send_check_errmsg(thd, table_list, "repair",
2310
error= send_check_errmsg(session, table_list, "repair",
2314
2311
"Failed generating table from .frm file");
2317
2314
if (my_rename(tmp, from, MYF(MY_WME)))
2319
2316
pthread_mutex_lock(&LOCK_open);
2320
unlock_table_name(thd, table_list);
2317
unlock_table_name(session, table_list);
2321
2318
pthread_mutex_unlock(&LOCK_open);
2322
error= send_check_errmsg(thd, table_list, "repair",
2319
error= send_check_errmsg(session, table_list, "repair",
2323
2320
"Failed restoring .MYD file");
2329
2326
to finish the repair in the handler later on.
2331
2328
pthread_mutex_lock(&LOCK_open);
2332
if (reopen_name_locked_table(thd, table_list, true))
2329
if (reopen_name_locked_table(session, table_list, true))
2334
unlock_table_name(thd, table_list);
2331
unlock_table_name(session, table_list);
2335
2332
pthread_mutex_unlock(&LOCK_open);
2336
error= send_check_errmsg(thd, table_list, "repair",
2333
error= send_check_errmsg(session, table_list, "repair",
2337
2334
"Failed to open partially repaired table");
2356
2353
false Message sent to net (admin operation went ok)
2357
true Message should be sent by caller
2354
true Message should be sent by caller
2358
2355
(admin operation or network communication failed)
2360
static bool mysql_admin_table(THD* thd, TableList* tables,
2357
static bool mysql_admin_table(Session* session, TableList* tables,
2361
2358
HA_CHECK_OPT* check_opt,
2362
2359
const char *operator_name,
2363
2360
thr_lock_type lock_type,
2364
2361
bool open_for_modify,
2365
2362
bool no_warnings_for_error,
2366
2363
uint32_t extra_open_options,
2367
int (*prepare_func)(THD *, TableList *,
2364
int (*prepare_func)(Session *, TableList *,
2368
2365
HA_CHECK_OPT *),
2369
int (handler::*operator_func)(THD *,
2366
int (handler::*operator_func)(Session *,
2370
2367
HA_CHECK_OPT *))
2372
2369
TableList *table;
2373
SELECT_LEX *select= &thd->lex->select_lex;
2370
Select_Lex *select= &session->lex->select_lex;
2374
2371
List<Item> field_list;
2376
Protocol *protocol= thd->protocol;
2373
Protocol *protocol= session->protocol;
2374
LEX *lex= session->lex;
2378
2375
int result_code= 0;
2379
2376
const CHARSET_INFO * const cs= system_charset_info;
2381
if (end_active_trans(thd))
2378
if (! session->endActiveTransaction())
2383
2380
field_list.push_back(item = new Item_empty_string("Table",
2384
2381
NAME_CHAR_LEN * 2,
2390
2387
item->maybe_null = 1;
2391
2388
field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
2392
2389
item->maybe_null = 1;
2393
if (protocol->send_fields(&field_list,
2394
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2390
if (protocol->sendFields(&field_list,
2391
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2397
mysql_ha_rm_tables(thd, tables, false);
2399
2394
for (table= tables; table; table= table->next_local)
2401
2396
char table_name[NAME_LEN*2+2];
2402
2397
char* db = table->db;
2403
2398
bool fatal_error=0;
2405
strxmov(table_name, db, ".", table->table_name, NULL);
2406
thd->open_options|= extra_open_options;
2400
sprintf(table_name,"%s.%s",db,table->table_name);
2401
session->open_options|= extra_open_options;
2407
2402
table->lock_type= lock_type;
2408
2403
/* open only one table from local list of command */
2422
2417
lex->query_tables= table;
2423
2418
lex->query_tables_last= &table->next_global;
2424
2419
lex->query_tables_own_last= 0;
2425
thd->no_warnings_for_error= no_warnings_for_error;
2420
session->no_warnings_for_error= no_warnings_for_error;
2427
open_and_lock_tables(thd, table);
2428
thd->no_warnings_for_error= 0;
2422
open_and_lock_tables(session, table);
2423
session->no_warnings_for_error= 0;
2429
2424
table->next_global= save_next_global;
2430
2425
table->next_local= save_next_local;
2431
thd->open_options&= ~extra_open_options;
2426
session->open_options&= ~extra_open_options;
2434
2429
if (prepare_func)
2436
switch ((*prepare_func)(thd, table, check_opt)) {
2431
switch ((*prepare_func)(session, table, check_opt)) {
2437
2432
case 1: // error, message written to net
2438
ha_autocommit_or_rollback(thd, 1);
2439
end_trans(thd, ROLLBACK);
2440
close_thread_tables(thd);
2433
ha_autocommit_or_rollback(session, 1);
2434
session->endTransaction(ROLLBACK);
2435
close_thread_tables(session);
2442
2437
case -1: // error, message could be written to net
2443
2438
/* purecov: begin inspected */
2469
2464
/* purecov: begin inspected */
2470
2465
char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
2471
2466
uint32_t length;
2472
protocol->prepare_for_resend();
2467
protocol->prepareForResend();
2473
2468
protocol->store(table_name, system_charset_info);
2474
2469
protocol->store(operator_name, system_charset_info);
2475
2470
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2476
2471
length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
2478
2473
protocol->store(buff, length, system_charset_info);
2479
ha_autocommit_or_rollback(thd, 0);
2480
end_trans(thd, COMMIT);
2481
close_thread_tables(thd);
2474
ha_autocommit_or_rollback(session, 0);
2475
session->endTransaction(COMMIT);
2476
close_thread_tables(session);
2482
2477
lex->reset_query_tables_list(false);
2483
2478
table->table=0; // For query cache
2484
2479
if (protocol->write())
2491
2486
if (lock_type == TL_WRITE && table->table->s->version)
2493
2488
pthread_mutex_lock(&LOCK_open);
2494
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
2489
const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2495
2490
"Waiting to get writelock");
2496
mysql_lock_abort(thd,table->table, true);
2497
remove_table_from_cache(thd, table->table->s->db.str,
2491
mysql_lock_abort(session,table->table, true);
2492
remove_table_from_cache(session, table->table->s->db.str,
2498
2493
table->table->s->table_name.str,
2499
2494
RTFC_WAIT_OTHER_THREAD_FLAG |
2500
2495
RTFC_CHECK_KILLED_FLAG);
2501
thd->exit_cond(old_message);
2496
session->exit_cond(old_message);
2497
if (session->killed)
2504
2499
open_for_modify= 0;
2518
2513
/* purecov: end */
2521
if (operator_func == &handler::ha_repair &&
2522
!(check_opt->sql_flags & TT_USEFRM))
2516
if (operator_func == &handler::ha_repair && !(check_opt->use_frm))
2524
2518
if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
2525
2519
(table->table->file->ha_check_for_upgrade(check_opt) ==
2526
2520
HA_ADMIN_NEEDS_ALTER))
2528
ha_autocommit_or_rollback(thd, 1);
2529
close_thread_tables(thd);
2530
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2531
result_code= mysql_recreate_table(thd, table);
2532
reenable_binlog(thd);
2522
ha_autocommit_or_rollback(session, 1);
2523
close_thread_tables(session);
2524
result_code= mysql_recreate_table(session, table);
2534
2526
mysql_recreate_table() can push OK or ERROR.
2535
2527
Clear 'OK' status. If there is an error, keep it:
2536
we will store the error message in a result set row
2528
we will store the error message in a result set row
2537
2529
and then clear.
2539
if (thd->main_da.is_ok())
2540
thd->main_da.reset_diagnostics_area();
2531
if (session->main_da.is_ok())
2532
session->main_da.reset_diagnostics_area();
2541
2533
goto send_result;
2545
result_code = (table->table->file->*operator_func)(thd, check_opt);
2537
result_code = (table->table->file->*operator_func)(session, check_opt);
2549
2541
lex->cleanup_after_one_table_open();
2550
thd->clear_error(); // these errors shouldn't get client
2542
session->clear_error(); // these errors shouldn't get client
2552
List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
2544
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2553
2545
DRIZZLE_ERROR *err;
2554
2546
while ((err= it++))
2556
protocol->prepare_for_resend();
2548
protocol->prepareForResend();
2557
2549
protocol->store(table_name, system_charset_info);
2558
2550
protocol->store((char*) operator_name, system_charset_info);
2559
2551
protocol->store(warning_level_names[err->level].str,
2635
2617
"try with alter", so here we close the table, do an ALTER Table,
2636
2618
reopen the table and do ha_innobase::analyze() on it.
2638
ha_autocommit_or_rollback(thd, 0);
2639
close_thread_tables(thd);
2620
ha_autocommit_or_rollback(session, 0);
2621
close_thread_tables(session);
2640
2622
TableList *save_next_local= table->next_local,
2641
2623
*save_next_global= table->next_global;
2642
2624
table->next_local= table->next_global= 0;
2643
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2644
result_code= mysql_recreate_table(thd, table);
2645
reenable_binlog(thd);
2625
result_code= mysql_recreate_table(session, table);
2647
2627
mysql_recreate_table() can push OK or ERROR.
2648
2628
Clear 'OK' status. If there is an error, keep it:
2649
we will store the error message in a result set row
2629
we will store the error message in a result set row
2650
2630
and then clear.
2652
if (thd->main_da.is_ok())
2653
thd->main_da.reset_diagnostics_area();
2654
ha_autocommit_or_rollback(thd, 0);
2655
close_thread_tables(thd);
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);
2656
2636
if (!result_code) // recreation went ok
2658
if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
2659
((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
2638
if ((table->table= open_ltable(session, table, lock_type, 0)) &&
2639
((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2660
2640
result_code= 0; // analyze went ok
2662
2642
if (result_code) // either mysql_recreate_table or analyze failed
2664
assert(thd->is_error());
2665
if (thd->is_error())
2644
assert(session->is_error());
2645
if (session->is_error())
2667
const char *err_msg= thd->main_da.message();
2647
const char *err_msg= session->main_da.message();
2648
if (!session->protocol->isConnected())
2670
sql_print_error(err_msg);
2650
errmsg_printf(ERRMSG_LVL_ERROR, "%s", err_msg);
2734
2706
pthread_mutex_lock(&LOCK_open);
2735
remove_table_from_cache(thd, table->table->s->db.str,
2707
remove_table_from_cache(session, table->table->s->db.str,
2736
2708
table->table->s->table_name.str, RTFC_NO_FLAG);
2737
2709
pthread_mutex_unlock(&LOCK_open);
2741
ha_autocommit_or_rollback(thd, 0);
2742
end_trans(thd, COMMIT);
2743
close_thread_tables(thd);
2713
ha_autocommit_or_rollback(session, 0);
2714
session->endTransaction(COMMIT);
2715
close_thread_tables(session);
2744
2716
table->table=0; // For query cache
2745
2717
if (protocol->write())
2753
ha_autocommit_or_rollback(thd, 1);
2754
end_trans(thd, ROLLBACK);
2755
close_thread_tables(thd); // Shouldn't be needed
2725
ha_autocommit_or_rollback(session, 1);
2726
session->endTransaction(ROLLBACK);
2727
close_thread_tables(session); // Shouldn't be needed
2757
2729
table->table=0;
2762
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
2734
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2764
return(mysql_admin_table(thd, tables, check_opt,
2765
"repair", TL_WRITE, 1,
2766
test(check_opt->sql_flags & TT_USEFRM),
2768
&prepare_for_repair,
2769
&handler::ha_repair));
2736
return(mysql_admin_table(session, tables, check_opt,
2737
"repair", TL_WRITE, 1,
2740
&prepare_for_repair,
2741
&handler::ha_repair));
2773
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
2745
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2775
return(mysql_admin_table(thd, tables, check_opt,
2776
"optimize", TL_WRITE, 1,0,0,0,
2777
&handler::ha_optimize));
2747
return(mysql_admin_table(session, tables, check_opt,
2748
"optimize", TL_WRITE, 1,0,0,0,
2749
&handler::ha_optimize));
2877
2849
local_create_info.default_table_charset=default_charset_info;
2878
2850
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2879
2851
schema_table->table->use_all_columns();
2880
if (mysql_prepare_alter_table(thd, schema_table->table,
2852
if (mysql_prepare_alter_table(session, schema_table->table,
2881
2853
&local_create_info, &alter_info))
2883
if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
2856
if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2884
2857
tmp_table, &db_options,
2885
2858
schema_table->table->file,
2886
2859
&schema_table->table->s->key_info, &keys, 0))
2888
2862
local_create_info.max_rows= 0;
2889
if (mysql_create_frm(thd, dst_path, NULL, NULL,
2863
if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
2890
2864
&local_create_info, alter_info.create_list,
2891
2865
keys, schema_table->table->s->key_info,
2892
schema_table->table->file))
2866
schema_table->table->file, true))
2899
2873
Create a table identical to the specified table
2902
2876
mysql_create_like_table()
2877
session Thread object
2904
2878
table Table list element for target table
2905
2879
src_table Table list element for source table
2906
2880
create_info Create info
2931
2905
we ensure that our statement is properly isolated from all concurrent
2932
2906
operations which matter.
2934
if (open_tables(thd, &src_table, ¬_used, 0))
2908
if (open_tables(session, &src_table, ¬_used, 0))
2937
strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
2911
strncpy(src_path, src_table->table->s->path.str, sizeof(src_path));
2940
2914
Check that destination tables does not exist. Note that its name
2941
2915
was already checked when it was added to the table list.
2943
2917
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2945
if (find_temporary_table(thd, db, table_name))
2919
if (find_temporary_table(session, db, table_name))
2946
2920
goto table_exists;
2947
dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
2921
dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2948
2922
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2952
if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
2926
if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2954
2928
if (!name_lock)
2955
2929
goto table_exists;
2956
2930
dst_path_length= build_table_filename(dst_path, sizeof(dst_path),
2957
db, table_name, reg_ext, 0);
2958
if (!access(dst_path, F_OK))
2931
db, table_name, "", 0);
2932
if (table_proto_exists(dst_path)==EEXIST)
2959
2933
goto table_exists;
2975
2949
pthread_mutex_lock(&LOCK_open);
2976
2950
if (src_table->schema_table)
2978
if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
2952
if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
2980
2954
pthread_mutex_unlock(&LOCK_open);
2984
else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
2986
if (my_errno == ENOENT)
2987
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2989
my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2990
pthread_mutex_unlock(&LOCK_open);
2960
int dfecopyr= copy_table_proto_file(src_path, dst_path);
2964
if (my_errno == ENOENT)
2965
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2967
my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2968
pthread_mutex_unlock(&LOCK_open);
2996
2975
creation, instead create the table directly (for both normal
2997
2976
and temporary tables).
2999
dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm
3000
if (thd->variables.keep_files_on_create)
2979
if (session->variables.keep_files_on_create)
3001
2980
create_info->options|= HA_CREATE_KEEP_FILES;
3002
err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
2981
err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
3003
2982
pthread_mutex_unlock(&LOCK_open);
3005
2984
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3007
if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
2986
if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3010
2989
(void) rm_temporary_table(create_info->db_type,
3011
dst_path, false); /* purecov: inspected */
3012
2991
goto err; /* purecov: inspected */
3057
3035
table->table= name_lock;
3058
3036
pthread_mutex_lock(&LOCK_open);
3059
if (reopen_name_locked_table(thd, table, false))
3037
if (reopen_name_locked_table(session, table, false))
3061
3039
pthread_mutex_unlock(&LOCK_open);
3064
3042
pthread_mutex_unlock(&LOCK_open);
3066
int result= store_create_info(thd, table, &query,
3044
int result= store_create_info(session, table, &query,
3069
3047
assert(result == 0); // store_create_info() always return 0
3070
write_bin_log(thd, true, query.ptr(), query.length());
3048
write_bin_log(session, true, query.ptr(), query.length());
3073
write_bin_log(thd, true, thd->query, thd->query_length);
3051
write_bin_log(session, true, session->query, session->query_length);
3076
3054
Case 3 and 4 does nothing under RBR
3080
write_bin_log(thd, true, thd->query, thd->query_length);
3101
3077
pthread_mutex_lock(&LOCK_open);
3102
unlink_open_table(thd, name_lock, false);
3078
unlink_open_table(session, name_lock, false);
3103
3079
pthread_mutex_unlock(&LOCK_open);
3109
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
3085
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3111
3087
thr_lock_type lock_type = TL_READ_NO_INSERT;
3113
return(mysql_admin_table(thd, tables, check_opt,
3089
return(mysql_admin_table(session, tables, check_opt,
3114
3090
"analyze", lock_type, 1, 0, 0, 0,
3115
3091
&handler::ha_analyze));
3119
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
3095
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3121
3097
thr_lock_type lock_type = TL_READ_NO_INSERT;
3123
return(mysql_admin_table(thd, tables, check_opt,
3099
return(mysql_admin_table(session, tables, check_opt,
3124
3100
"check", lock_type,
3125
3101
0, 0, HA_OPEN_FOR_REPAIR, 0,
3126
3102
&handler::ha_check));
3150
3126
We set this flag so that ha_innobase::open and ::external_lock() do
3151
3127
not complain when we lock the table
3153
thd->tablespace_op= true;
3154
if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
3129
session->tablespace_op= true;
3130
if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3156
thd->tablespace_op=false;
3132
session->tablespace_op=false;
3160
3136
error= table->file->ha_discard_or_import_tablespace(discard);
3162
thd_proc_info(thd, "end");
3138
session->set_proc_info("end");
3167
3143
/* The ALTER Table is always in its own transaction */
3168
error = ha_autocommit_or_rollback(thd, 0);
3169
if (end_active_trans(thd))
3144
error = ha_autocommit_or_rollback(session, 0);
3145
if (! session->endActiveTransaction())
3173
write_bin_log(thd, false, thd->query, thd->query_length);
3149
write_bin_log(session, false, session->query, session->query_length);
3176
ha_autocommit_or_rollback(thd, error);
3177
thd->tablespace_op=false;
3152
ha_autocommit_or_rollback(session, error);
3153
session->tablespace_op=false;
3179
3155
if (error == 0)
3185
3161
table->file->print_error(error, MYF(0));
3196
3172
uint32_t flags= alter_info->flags;
3198
3174
if (ALTER_ADD_COLUMN & flags)
3199
*alter_flags|= HA_ADD_COLUMN;
3175
alter_flags->set(HA_ADD_COLUMN);
3200
3176
if (ALTER_DROP_COLUMN & flags)
3201
*alter_flags|= HA_DROP_COLUMN;
3177
alter_flags->set(HA_DROP_COLUMN);
3202
3178
if (ALTER_RENAME & flags)
3203
*alter_flags|= HA_RENAME_TABLE;
3179
alter_flags->set(HA_RENAME_TABLE);
3204
3180
if (ALTER_CHANGE_COLUMN & flags)
3205
*alter_flags|= HA_CHANGE_COLUMN;
3181
alter_flags->set(HA_CHANGE_COLUMN);
3206
3182
if (ALTER_COLUMN_DEFAULT & flags)
3207
*alter_flags|= HA_COLUMN_DEFAULT_VALUE;
3183
alter_flags->set(HA_COLUMN_DEFAULT_VALUE);
3208
3184
if (ALTER_COLUMN_STORAGE & flags)
3209
*alter_flags|= HA_COLUMN_STORAGE;
3185
alter_flags->set(HA_COLUMN_STORAGE);
3210
3186
if (ALTER_COLUMN_FORMAT & flags)
3211
*alter_flags|= HA_COLUMN_FORMAT;
3187
alter_flags->set(HA_COLUMN_FORMAT);
3212
3188
if (ALTER_COLUMN_ORDER & flags)
3213
*alter_flags|= HA_ALTER_COLUMN_ORDER;
3189
alter_flags->set(HA_ALTER_COLUMN_ORDER);
3214
3190
if (ALTER_STORAGE & flags)
3215
*alter_flags|= HA_ALTER_STORAGE;
3191
alter_flags->set(HA_ALTER_STORAGE);
3216
3192
if (ALTER_ROW_FORMAT & flags)
3217
*alter_flags|= HA_ALTER_ROW_FORMAT;
3193
alter_flags->set(HA_ALTER_ROW_FORMAT);
3218
3194
if (ALTER_RECREATE & flags)
3219
*alter_flags|= HA_RECREATE;
3195
alter_flags->set(HA_RECREATE);
3220
3196
if (ALTER_FOREIGN_KEY & flags)
3221
*alter_flags|= HA_ALTER_FOREIGN_KEY;
3197
alter_flags->set(HA_ALTER_FOREIGN_KEY);
3202
@param session Thread
3227
3203
@param table The original table.
3228
3204
@param alter_info Alter options, fields and keys for the new
3355
3326
create_info->used_fields & HA_CREATE_USED_ROW_FORMAT ||
3356
3327
(alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
3358
!table->s->mysql_version ||
3359
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
3329
!table->s->mysql_version)
3361
3331
*table_changes= IS_EQUAL_NO;
3363
3333
Check what has changed and set alter_flags
3365
3335
if (table->s->fields < alter_info->create_list.elements)
3366
*alter_flags|= HA_ADD_COLUMN;
3336
alter_flags->set(HA_ADD_COLUMN);
3367
3337
else if (table->s->fields > alter_info->create_list.elements)
3368
*alter_flags|= HA_DROP_COLUMN;
3338
alter_flags->set(HA_DROP_COLUMN);
3369
3339
if (create_info->db_type != table->s->db_type() ||
3370
3340
create_info->used_fields & HA_CREATE_USED_ENGINE)
3371
*alter_flags|= HA_ALTER_STORAGE_ENGINE;
3341
alter_flags->set(HA_ALTER_STORAGE_ENGINE);
3372
3342
if (create_info->used_fields & HA_CREATE_USED_CHARSET)
3373
*alter_flags|= HA_CHANGE_CHARACTER_SET;
3343
alter_flags->set(HA_CHANGE_CHARACTER_SET);
3374
3344
if (create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)
3375
*alter_flags|= HA_SET_DEFAULT_CHARACTER_SET;
3345
alter_flags->set(HA_SET_DEFAULT_CHARACTER_SET);
3376
3346
if (alter_info->flags & ALTER_RECREATE)
3377
*alter_flags|= HA_RECREATE;
3347
alter_flags->set(HA_RECREATE);
3378
3348
/* TODO check for ADD/DROP FOREIGN KEY */
3379
3349
if (alter_info->flags & ALTER_FOREIGN_KEY)
3380
*alter_flags|= HA_ALTER_FOREIGN_KEY;
3381
if (!table->s->mysql_version ||
3382
(table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
3383
*alter_flags|= HA_ALTER_COLUMN_TYPE;
3350
alter_flags->set(HA_ALTER_FOREIGN_KEY);
3386
3353
Go through fields and check if the original ones are compatible
3414
3389
new_field->field_name))
3416
3391
field->flags|= FIELD_IS_RENAMED;
3417
*alter_flags|= HA_ALTER_COLUMN_NAME;
3392
alter_flags->set(HA_ALTER_COLUMN_NAME);
3420
3395
*table_changes&= table_changes_local;
3421
3396
if (table_changes_local == IS_EQUAL_PACK_LENGTH)
3422
*alter_flags|= HA_ALTER_COLUMN_TYPE;
3397
alter_flags->set(HA_ALTER_COLUMN_TYPE);
3424
3399
/* Check that NULL behavior is same for old and new fields */
3425
3400
if ((new_field->flags & NOT_NULL_FLAG) !=
3426
(uint) (field->flags & NOT_NULL_FLAG))
3401
(uint32_t) (field->flags & NOT_NULL_FLAG))
3428
3403
*table_changes= IS_EQUAL_NO;
3429
*alter_flags|= HA_ALTER_COLUMN_NULLABLE;
3404
alter_flags->set(HA_ALTER_COLUMN_NULLABLE);
3751
3719
char tmp_name[80];
3752
3720
char path[FN_REFLEN];
3754
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3755
tmp_file_prefix, current_pid, thd->thread_id);
3722
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
3723
TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3756
3724
/* Safety fix for InnoDB */
3757
3725
if (lower_case_table_names)
3758
3726
my_casedn_str(files_charset_info, tmp_name);
3759
3727
altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
3760
altered_create_info.frm_only= 1;
3761
if ((error= create_temporary_table(thd, table, new_db, tmp_name,
3729
if ((error= create_temporary_table(session, table, new_db, tmp_name,
3762
3730
&altered_create_info,
3763
3731
alter_info, db_change)))
3846
3812
and will be renamed to the original table name.
3848
3814
pthread_mutex_lock(&LOCK_open);
3849
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3815
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3850
3816
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3852
close_data_files_and_morph_locks(thd,
3818
close_data_files_and_morph_locks(session,
3853
3819
table->pos_in_table_list->db,
3854
3820
table->pos_in_table_list->table_name);
3855
3821
if (mysql_rename_table(NULL,
4088
4061
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
4092
4065
Check that the DATE/DATETIME not null field we are going to add is
4093
4066
either has a default value or the '0000-00-00' is allowed by the
4095
4068
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4096
4069
flag to allow ALTER Table only if the table to be altered is empty.
4098
if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
4071
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4099
4072
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4100
!alter_info->datetime_field &&
4101
!(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4102
thd->variables.sql_mode & MODE_NO_ZERO_DATE)
4073
!alter_info->datetime_field &&
4074
!(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4075
session->variables.sql_mode & MODE_NO_ZERO_DATE)
4104
alter_info->datetime_field= def;
4105
alter_info->error_if_not_empty= true;
4077
alter_info->datetime_field= def;
4078
alter_info->error_if_not_empty= true;
4107
4080
if (!def->after)
4108
4081
new_create_list.push_back(def);
4361
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
4336
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4362
4337
HA_CREATE_INFO *create_info,
4363
4338
TableList *table_list,
4364
4339
Alter_info *alter_info,
4365
4340
uint32_t order_num, order_st *order, bool ignore)
4367
4342
Table *table, *new_table=0, *name_lock= 0;;
4343
string new_name_str;
4369
4345
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4370
4346
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4371
4347
char path[FN_REFLEN];
4372
4348
ha_rows copied= 0,deleted= 0;
4373
handlerton *old_db_type, *new_db_type, *save_old_db_type;
4374
legacy_db_type table_type;
4349
StorageEngine *old_db_type, *new_db_type, *save_old_db_type;
4351
new_name_buff[0]= '\0';
4376
4353
if (table_list && table_list->schema_table)
4378
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
4355
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4393
4370
build_table_filename(path, sizeof(path), db, table_name, "", 0);
4395
mysql_ha_rm_tables(thd, table_list, false);
4397
4372
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4398
4373
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4399
4374
/* Conditionally writes to binlog. */
4400
return(mysql_discard_or_import_tablespace(thd,table_list,
4375
return(mysql_discard_or_import_tablespace(session,table_list,
4401
4376
alter_info->tablespace_op));
4402
strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db,
4403
"/", table_name, reg_ext, NULL);
4404
(void) unpack_filename(new_name_buff, new_name_buff);
4378
oss << drizzle_data_home << "/" << db << "/" << table_name;
4380
(void) unpack_filename(new_name_buff, oss.str().c_str());
4406
4382
If this is just a rename of a view, short cut to the
4407
4383
following scenario: 1) lock LOCK_open 2) do a RENAME
4415
4391
into the main table list, like open_tables does).
4416
4392
This code is wrong and will be removed, please do not copy.
4418
(void)mysql_frm_type(thd, new_name_buff, &table_type);
4420
if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
4395
if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4422
4397
table->use_all_columns();
4424
4399
/* Check that we are not trying to rename to an existing table */
4427
my_stpcpy(new_name_buff,new_name);
4428
my_stpcpy(new_alias= new_alias_buff, new_name);
4402
strcpy(new_name_buff,new_name);
4403
strcpy(new_alias= new_alias_buff, new_name);
4429
4404
if (lower_case_table_names)
4431
4406
if (lower_case_table_names != 2)
4433
my_casedn_str(files_charset_info, new_name_buff);
4434
new_alias= new_name; // Create lower case table name
4408
my_casedn_str(files_charset_info, new_name_buff);
4409
new_alias= new_name; // Create lower case table name
4436
4411
my_casedn_str(files_charset_info, new_name);
4527
4502
from concurrent DDL statements.
4529
4504
pthread_mutex_lock(&LOCK_open);
4530
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4505
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4531
4506
pthread_mutex_unlock(&LOCK_open);
4532
4507
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4533
4508
/* COND_refresh will be signaled in close_thread_tables() */
4536
4511
pthread_mutex_lock(&LOCK_open);
4537
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4512
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4538
4513
pthread_mutex_unlock(&LOCK_open);
4539
4514
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4540
4515
/* COND_refresh will be signaled in close_thread_tables() */
4638
4613
new_db_type= create_info->db_type;
4640
if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
4615
if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4643
set_table_default_charset(thd, create_info, db);
4646
if (thd->variables.old_alter_table
4618
set_table_default_charset(session, create_info, db);
4620
if (session->variables.old_alter_table
4647
4621
|| (table->s->db_type() != create_info->db_type)
4650
4624
if (alter_info->build_method == HA_BUILD_ONLINE)
4652
my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4626
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4655
4629
alter_info->build_method= HA_BUILD_OFFLINE;
4720
4694
case HA_ALTER_NOT_SUPPORTED:
4721
4695
if (alter_info->build_method == HA_BUILD_ONLINE)
4723
my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4724
close_temporary_table(thd, altered_table, 1, 1);
4697
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4698
close_temporary_table(session, altered_table, 1, 1);
4727
4701
need_copy_table= true;
4729
4703
case HA_ALTER_ERROR:
4731
close_temporary_table(thd, altered_table, 1, 1);
4705
close_temporary_table(session, altered_table, 1, 1);
4772
4746
if (altered_table)
4773
close_temporary_table(thd, altered_table, 1, 1);
4747
close_temporary_table(session, altered_table, 1, 1);
4776
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4777
current_pid, thd->thread_id);
4750
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
4751
(unsigned long)current_pid, session->thread_id);
4778
4752
/* Safety fix for innodb */
4779
4753
if (lower_case_table_names)
4780
4754
my_casedn_str(files_charset_info, tmp_name);
4783
4757
/* Create a temporary table with the new format */
4784
if ((error= create_temporary_table(thd, table, new_db, tmp_name,
4785
create_info, alter_info,
4758
if ((error= create_temporary_table(session, table, new_db, tmp_name,
4759
create_info, alter_info,
4786
4760
!strcmp(db, new_db))))
4795
4769
memset(&tbl, 0, sizeof(tbl));
4796
4770
tbl.db= new_db;
4797
4771
tbl.table_name= tbl.alias= tmp_name;
4798
/* Table is in thd->temporary_tables */
4799
new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4772
/* Table is in session->temporary_tables */
4773
new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4803
char path[FN_REFLEN];
4777
char tmp_path[FN_REFLEN];
4804
4778
/* table is a normal table: Create temporary table in same directory */
4805
build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4779
build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, "",
4807
4781
/* Open our intermediate table */
4808
new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
4782
new_table=open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
4810
4784
if (!new_table)
4813
4787
/* Copy the data if necessary. */
4814
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
4815
thd->cuted_fields=0L;
4816
thd_proc_info(thd, "copy to tmp table");
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");
4817
4791
copied=deleted=0;
4819
4793
We do not copy data for MERGE tables. Only the children have data.
4835
4809
pthread_mutex_lock(&LOCK_open);
4836
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4810
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4837
4811
pthread_mutex_unlock(&LOCK_open);
4838
4812
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4839
4813
alter_info->keys_onoff);
4840
error= ha_autocommit_or_rollback(thd, 0);
4841
if (end_active_trans(thd))
4814
error= ha_autocommit_or_rollback(session, 0);
4815
if (! session->endActiveTransaction())
4844
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
4818
/* We must not ignore bad input! */;
4819
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
4846
4821
if (table->s->tmp_table != NO_TMP_TABLE)
4851
4826
/* Close lock if this is a transactional table */
4854
mysql_unlock_tables(thd, thd->lock);
4829
mysql_unlock_tables(session, session->lock);
4857
4832
/* Remove link to old table and rename the new one */
4858
close_temporary_table(thd, table, 1, 1);
4833
close_temporary_table(session, table, 1, 1);
4859
4834
/* Should pass the 'new_name' as we store table name in the cache */
4860
if (rename_temporary_table(thd, new_table, new_db, new_name))
4835
if (rename_temporary_table(session, new_table, new_db, new_name))
4862
/* We don't replicate alter table statement on temporary tables */
4863
if (!thd->current_stmt_binlog_row_based)
4864
write_bin_log(thd, true, thd->query, thd->query_length);
4865
4837
goto end_temporary;
4898
4870
call to remove name-locks from table cache and list of open table.
4901
thd_proc_info(thd, "rename result table");
4902
snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
4903
current_pid, thd->thread_id);
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);
4904
4876
if (lower_case_table_names)
4905
4877
my_casedn_str(files_charset_info, old_name);
4907
wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4908
close_data_files_and_morph_locks(thd, db, table_name);
4879
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
4880
close_data_files_and_morph_locks(session, db, table_name);
4911
4883
save_old_db_type= old_db_type;
4949
4921
quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4952
if (thd->locked_tables && new_name == table_name && new_db == db)
4924
if (session->locked_tables && new_name == table_name && new_db == db)
4954
thd->in_lock_tables= 1;
4955
error= reopen_tables(thd, 1, 1);
4956
thd->in_lock_tables= 0;
4926
session->in_lock_tables= 1;
4927
error= reopen_tables(session, 1, 1);
4928
session->in_lock_tables= 0;
4958
4930
goto err_with_placeholders;
4960
4932
pthread_mutex_unlock(&LOCK_open);
4962
thd_proc_info(thd, "end");
4964
assert(!(mysql_bin_log.is_open() &&
4965
thd->current_stmt_binlog_row_based &&
4966
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4967
write_bin_log(thd, true, thd->query, thd->query_length);
4969
if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
4934
session->set_proc_info("end");
4936
write_bin_log(session, true, session->query, session->query_length);
4938
if (old_db_type->check_flag(HTON_BIT_FLUSH_AFTER_RENAME))
4972
4941
For the alter table to be properly flushed to the logs, we
4973
4942
have to open the new table. If not, we get a problem on server
4974
4943
shutdown. But we do not need to attach MERGE children.
4976
char path[FN_REFLEN];
4945
char table_path[FN_REFLEN];
4977
4946
Table *t_table;
4978
build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
4979
t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
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);
4982
4951
intern_close_table(t_table);
4986
sql_print_warning(_("Could not open table %s.%s after rename\n"),
4955
errmsg_printf(ERRMSG_LVL_WARN,
4956
_("Could not open table %s.%s after rename\n"),
4988
4958
ha_flush_logs(old_db_type);
4990
4960
table_list->table=0; // For query cache
4992
if (thd->locked_tables && (new_name != table_name || new_db != db))
4962
if (session->locked_tables && (new_name != table_name || new_db != db))
4995
4965
If are we under LOCK TABLES and did ALTER Table with RENAME we need
4998
4968
LOCK TABLES we can rely on close_thread_tables() doing this job.
5000
4970
pthread_mutex_lock(&LOCK_open);
5001
unlink_open_table(thd, table, false);
5002
unlink_open_table(thd, name_lock, false);
4971
unlink_open_table(session, table, false);
4972
unlink_open_table(session, name_lock, false);
5003
4973
pthread_mutex_unlock(&LOCK_open);
5007
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5008
(ulong) (copied + deleted), (ulong) deleted,
5009
(ulong) thd->cuted_fields);
5010
my_ok(thd, copied + deleted, 0L, tmp_name);
5011
thd->some_tables_deleted=0;
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.
4982
if (! session->is_error())
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;
4993
/* my_error() was called. Return true (which means error...) */
5017
5000
/* close_temporary_table() frees the new_table pointer. */
5018
close_temporary_table(thd, new_table, 1, 1);
5001
close_temporary_table(session, new_table, 1, 1);
5021
5004
quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5045
5028
/* Shouldn't get here. */
5048
bool save_abort_on_warning= thd->abort_on_warning;
5049
thd->abort_on_warning= true;
5050
make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
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,
5051
5034
f_val, strlength(f_val), t_type,
5052
5035
alter_info->datetime_field->field_name);
5053
thd->abort_on_warning= save_abort_on_warning;
5036
session->abort_on_warning= save_abort_on_warning;
5057
5040
pthread_mutex_lock(&LOCK_open);
5058
unlink_open_table(thd, name_lock, false);
5041
unlink_open_table(session, name_lock, false);
5059
5042
pthread_mutex_unlock(&LOCK_open);
5103
5086
Turn off recovery logging since rollback of an alter table is to
5104
5087
delete the new table so there is no need to log the changes to it.
5106
5089
This needs to be done before external_lock
5108
error= ha_enable_transaction(thd, false);
5091
error= ha_enable_transaction(session, false);
5112
5095
if (!(copy= new Copy_field[to->s->fields]))
5113
5096
return(-1); /* purecov: inspected */
5115
if (to->file->ha_external_lock(thd, F_WRLCK))
5098
if (to->file->ha_external_lock(session, F_WRLCK))
5118
5101
/* We need external lock before we can disable/enable keys */
5119
5102
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5121
5104
/* We can abort alter table for any table type */
5122
thd->abort_on_warning= !ignore;
5105
session->abort_on_warning= !ignore;
5124
5107
from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5125
5108
to->file->ha_start_bulk_insert(from->file->stats.records);
5127
save_sql_mode= thd->variables.sql_mode;
5110
save_sql_mode= session->variables.sql_mode;
5129
5112
List_iterator<Create_field> it(create);
5130
5113
Create_field *def;
5149
5132
if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5151
5134
char warn_buff[DRIZZLE_ERRMSG_SIZE];
5152
snprintf(warn_buff, sizeof(warn_buff),
5135
snprintf(warn_buff, sizeof(warn_buff),
5153
5136
_("order_st BY ignored because there is a user-defined clustered "
5154
5137
"index in the table '%-.192s'"),
5155
5138
from->s->table_name.str);
5156
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5139
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5161
from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5162
MYF(MY_FAE | MY_ZEROFILL));
5144
from->sort.io_cache= new IO_CACHE;
5145
memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
5163
5147
memset(&tables, 0, sizeof(tables));
5164
5148
tables.table= from;
5165
5149
tables.alias= tables.table_name= from->s->table_name.str;
5166
5150
tables.db= from->s->db.str;
5169
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5170
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
5153
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
5154
setup_order(session, session->lex->select_lex.ref_pointer_array,
5171
5155
&tables, fields, all_fields, order) ||
5172
5156
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5173
(from->sort.found_records= filesort(thd, from, sortorder, length,
5157
(from->sort.found_records= filesort(session, from, sortorder, length,
5174
5158
(SQL_SELECT *) 0, HA_POS_ERROR,
5175
5159
1, &examined_rows)) ==
5181
5165
/* Tell handler that we have values for all columns in the to table */
5182
5166
to->use_all_columns();
5183
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
5167
init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
5185
5169
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5170
session->row_count= 0;
5187
5171
restore_record(to, s->default_values); // Create empty record
5188
5172
while (!(error=info.read_record(&info)))
5174
if (session->killed)
5192
thd->send_kill_message();
5176
session->send_kill_message();
5180
session->row_count++;
5197
5181
/* Return error if source table isn't empty. */
5198
5182
if (error_if_not_empty)
5265
5250
Ensure that the new table is saved properly to disk so that we
5266
5251
can do a rename
5268
if (ha_autocommit_or_rollback(thd, 0))
5253
if (ha_autocommit_or_rollback(session, 0))
5270
if (end_active_trans(thd))
5255
if (! session->endActiveTransaction())
5274
thd->variables.sql_mode= save_sql_mode;
5275
thd->abort_on_warning= 0;
5259
session->variables.sql_mode= save_sql_mode;
5260
session->abort_on_warning= 0;
5276
5261
free_io_cache(from);
5277
5262
*copied= found_count;
5278
5263
*deleted=delete_count;
5279
5264
to->file->ha_release_auto_increment();
5280
if (to->file->ha_external_lock(thd,F_UNLCK))
5265
if (to->file->ha_external_lock(session,F_UNLCK))
5282
5267
return(error > 0 ? -1 : 0);
5311
5296
create_info.default_table_charset=default_charset_info;
5312
5297
/* Force alter table to recreate table */
5313
5298
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5314
return(mysql_alter_table(thd, NULL, NULL, &create_info,
5299
return(mysql_alter_table(session, NULL, NULL, &create_info,
5315
5300
table_list, &alter_info, 0,
5316
5301
(order_st *) 0, 0));
5320
bool mysql_checksum_table(THD *thd, TableList *tables,
5305
bool mysql_checksum_table(Session *session, TableList *tables,
5321
5306
HA_CHECK_OPT *check_opt)
5323
5308
TableList *table;
5324
5309
List<Item> field_list;
5326
Protocol *protocol= thd->protocol;
5311
Protocol *protocol= session->protocol;
5328
5313
field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5329
5314
item->maybe_null= 1;
5330
5315
field_list.push_back(item= new Item_int("Checksum", (int64_t) 1,
5331
5316
MY_INT64_NUM_DECIMAL_DIGITS));
5332
5317
item->maybe_null= 1;
5333
if (protocol->send_fields(&field_list,
5334
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
5318
if (protocol->sendFields(&field_list,
5319
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
5337
5322
/* Open one table after the other to keep lock time as short as possible. */
5340
5325
char table_name[NAME_LEN*2+2];
5343
strxmov(table_name, table->db ,".", table->table_name, NULL);
5345
t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5346
thd->clear_error(); // these errors shouldn't get client
5348
protocol->prepare_for_resend();
5328
sprintf(table_name,"%s.%s",table->db,table->table_name);
5330
t= table->table= open_n_lock_single_table(session, table, TL_READ);
5331
session->clear_error(); // these errors shouldn't get client
5333
protocol->prepareForResend();
5349
5334
protocol->store(table_name, system_charset_info);
5353
5338
/* Table didn't exist */
5354
protocol->store_null();
5340
session->clear_error();
5415
5400
t->file->ha_rnd_end();
5419
close_thread_tables(thd);
5403
session->clear_error();
5404
close_thread_tables(session);
5420
5405
table->table=0; // For query cache
5422
5407
if (protocol->write())
5430
close_thread_tables(thd); // Shouldn't be needed
5415
close_thread_tables(session); // Shouldn't be needed
5432
5417
table->table=0;
5436
static bool check_engine(THD *thd, const char *table_name,
5421
static bool check_engine(Session *session, const char *table_name,
5437
5422
HA_CREATE_INFO *create_info)
5439
handlerton **new_engine= &create_info->db_type;
5440
handlerton *req_engine= *new_engine;
5441
bool no_substitution= 1;
5442
if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
5443
no_substitution, 1)))
5424
StorageEngine **new_engine= &create_info->db_type;
5425
StorageEngine *req_engine= *new_engine;
5426
if (!req_engine->is_enabled())
5428
string engine_name= req_engine->getName();
5429
my_error(ER_FEATURE_DISABLED,MYF(0),
5430
engine_name.c_str(), engine_name.c_str());
5446
5435
if (req_engine && req_engine != *new_engine)
5448
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5437
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5449
5438
ER_WARN_USING_OTHER_HANDLER,
5450
5439
ER(ER_WARN_USING_OTHER_HANDLER),
5451
ha_resolve_storage_engine_name(*new_engine),
5440
ha_resolve_storage_engine_name(*new_engine).c_str(),
5454
5443
if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5455
ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
5444
(*new_engine)->check_flag(HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5457
5446
if (create_info->used_fields & HA_CREATE_USED_ENGINE)
5459
5448
my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
5460
ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
5449
ha_resolve_storage_engine_name(*new_engine).c_str(),
5461
5451
*new_engine= 0;
5464
*new_engine= myisam_hton;
5454
*new_engine= myisam_engine;