18
18
#include <drizzled/server_includes.h>
19
19
#include <storage/myisam/myisam.h>
20
#include <drizzled/show.h>
21
#include <drizzled/error.h>
22
#include <drizzled/gettext.h>
23
#include <drizzled/data_home.h>
24
#include <drizzled/sql_parse.h>
25
#include <mysys/hash.h>
26
#include <drizzled/sql_lex.h>
27
#include <drizzled/session.h>
28
#include <drizzled/sql_base.h>
29
#include <drizzled/db.h>
30
#include <drizzled/lock.h>
31
#include <drizzled/unireg.h>
32
#include <drizzled/item/int.h>
33
#include <drizzled/item/empty_string.h>
34
#include <drizzled/replicator.h>
38
extern HASH lock_db_cache;
20
#include <drizzled/sql_show.h>
21
#include <drizzled/drizzled_error_messages.h>
22
#include <libdrizzle/gettext.h>
40
24
int creating_table= 0; // How many mysql_create_table are running
43
bool is_primary_key(KEY *key_info)
45
static const char * primary_key_name="PRIMARY";
46
return (strcmp(key_info->name, primary_key_name)==0);
49
const char* is_primary_key_name(const char* key_name)
51
static const char * primary_key_name="PRIMARY";
52
if (strcmp(key_name, primary_key_name)==0)
26
const char *primary_key_name="PRIMARY";
58
28
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
59
29
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
64
34
enum enum_enable_or_disable keys_onoff,
65
35
bool error_if_not_empty);
67
static bool prepare_blob_field(Session *session, Create_field *sql_field);
68
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
37
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
38
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
70
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
71
41
Alter_info *alter_info,
73
43
uint32_t *db_options,
74
44
handler *file, KEY **key_info_buffer,
75
45
uint32_t *key_count, int select_field_count);
77
mysql_prepare_alter_table(Session *session, Table *table,
47
mysql_prepare_alter_table(THD *thd, Table *table,
78
48
HA_CREATE_INFO *create_info,
79
49
Alter_info *alter_info);
81
static void set_table_default_charset(Session *session,
82
HA_CREATE_INFO *create_info, char *db)
85
If the table character set was not given explicitly,
86
let's fetch the database default character set and
87
apply it to the table.
89
if (!create_info->default_table_charset)
91
HA_CREATE_INFO db_info;
93
load_db_opt_by_name(session, db, &db_info);
95
create_info->default_table_charset= db_info.default_table_charset;
100
52
Translate a file name to a table name (WL #1324).
193
150
build_tmptable_filename() for them.
196
path length on success, 0 on failure
199
156
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
200
157
const char *table_name, const char *ext, uint32_t flags)
203
159
char dbbuff[FN_REFLEN];
204
160
char tbbuff[FN_REFLEN];
205
int rootdir_len= strlen(FN_ROOTDIR);
207
162
if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
208
strncpy(tbbuff, table_name, sizeof(tbbuff));
163
my_stpncpy(tbbuff, table_name, sizeof(tbbuff));
210
165
tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
212
167
tablename_to_filename(db, dbbuff, sizeof(dbbuff));
213
table_path= drizzle_data_home;
214
int without_rootdir= table_path.length()-rootdir_len;
216
/* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
217
if (without_rootdir >= 0)
219
char *tmp= (char*)table_path.c_str()+without_rootdir;
220
if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
221
table_path.append(FN_ROOTDIR);
224
table_path.append(dbbuff);
225
table_path.append(FN_ROOTDIR);
169
char *end = buff + bufflen;
170
/* Don't add FN_ROOTDIR if mysql_data_home already includes it */
171
char *pos = my_stpncpy(buff, mysql_data_home, bufflen);
172
int rootdir_len= strlen(FN_ROOTDIR);
173
if (pos - rootdir_len >= buff &&
174
memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
175
pos= my_stpncpy(pos, FN_ROOTDIR, end - pos);
176
pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NULL);
226
177
#ifdef USE_SYMDIR
178
unpack_dirname(buff, buff);
229
table_path.append(tbbuff);
230
table_path.append(ext);
232
if (bufflen < table_path.length())
235
strcpy(buff, table_path.c_str());
236
return table_path.length();
181
pos= strxnmov(pos, end - pos, tbbuff, ext, NULL);
241
Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
188
Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
244
191
build_tmptable_filename()
245
session The thread handle.
192
thd The thread handle.
246
193
buff Where to write result in my_charset_filename.
247
194
bufflen buff size
251
198
Uses current_pid, thread_id, and tmp_table counter to create
252
a file name in drizzle_tmpdir.
199
a file name in mysql_tmpdir.
255
path length on success, 0 on failure
258
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
205
uint32_t build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
261
ostringstream path_str, post_tmpdir_str;
264
path_str << drizzle_tmpdir;
265
post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
266
post_tmpdir_str << session->thread_id << session->tmp_table++;
267
tmp= post_tmpdir_str.str();
208
char *p= my_stpncpy(buff, mysql_tmpdir, bufflen);
209
snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
210
tmp_file_prefix, current_pid,
211
thd->thread_id, thd->tmp_table++, reg_ext);
269
213
if (lower_case_table_names)
270
transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
274
if (bufflen < path_str.str().length())
277
length= unpack_filename(buff, path_str.str().c_str());
215
/* Convert all except tmpdir to lower case */
216
my_casedn_str(files_charset_info, p);
219
uint32_t length= unpack_filename(buff, buff);
285
session Thread object
286
227
clear_error is clear_error to be called
287
228
query Query to log
288
229
query_length Length of query
391
338
-1 Thread was killed
394
int mysql_rm_table_part2(Session *session, TableList *tables, bool if_exists,
395
bool drop_temporary, bool dont_log_query)
341
int mysql_rm_table_part2(THD *thd, TableList *tables, bool if_exists,
342
bool drop_temporary, bool drop_view,
397
345
TableList *table;
398
346
char path[FN_REFLEN], *alias;
399
uint32_t path_length= 0;
347
uint32_t path_length;
400
348
String wrong_tables;
402
350
int non_temp_tables_count= 0;
403
351
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
404
352
String built_query;
354
if (thd->current_stmt_binlog_row_based && !dont_log_query)
408
356
built_query.set_charset(system_charset_info);
485
438
if (!drop_temporary)
487
440
Table *locked_table;
488
abort_locked_tables(session, db, table->table_name);
489
remove_table_from_cache(session, db, table->table_name,
441
abort_locked_tables(thd, db, table->table_name);
442
remove_table_from_cache(thd, db, table->table_name,
490
443
RTFC_WAIT_OTHER_THREAD_FLAG |
491
444
RTFC_CHECK_KILLED_FLAG);
493
446
If the table was used in lock tables, remember it so that
494
447
unlock_table_names can free it
496
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
449
if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
497
450
table->table= locked_table;
502
455
goto err_with_placeholders;
504
457
alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
505
458
/* remove .frm file and engine files */
506
path_length= build_table_filename(path, sizeof(path), db, alias, "",
459
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
507
460
table->internal_tmp_table ?
510
463
if (drop_temporary ||
511
((table_type == NULL && (table_proto_exists(path)!=EEXIST))))
464
((table_type == NULL && (access(path, F_OK) && ha_create_table_from_engine(thd, db, alias))) ||
465
(!drop_view && mysql_frm_type(thd, path, &frm_db_type) != true)))
513
467
// Table was not found on disk and table can't be created from engine
515
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
469
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
516
470
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
517
471
table->table_name);
523
error= ha_delete_table(session, path, db, 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
486
!dont_log_query);
525
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
487
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
488
(if_exists || table_type == NULL))
529
session->clear_error();
531
493
if (error == HA_ERR_ROW_IS_REFERENCED)
642
bool quick_rm_table(handlerton *,const char *db,
607
bool quick_rm_table(handlerton *base,const char *db,
643
608
const char *table_name, uint32_t flags)
645
610
char path[FN_REFLEN];
648
build_table_filename(path, sizeof(path), db, table_name, "", flags);
650
error= delete_table_proto_file(path);
652
return(ha_delete_table(current_session, path, db, table_name, 0) ||
613
uint32_t path_length= build_table_filename(path, sizeof(path),
614
db, table_name, reg_ext, flags);
615
if (my_delete(path,MYF(0)))
616
error= 1; /* purecov: inspected */
617
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
618
return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
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;
1635
1603
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);
1677
1682
mysql_create_table_no_lock()
1678
session Thread object
1680
1685
table_name Table name
1681
1686
create_info Create information (like MAX_ROWS)
1728
if (check_engine(session, table_name, create_info))
1732
if (check_engine(thd, table_name, create_info))
1730
1734
db_options= create_info->table_options;
1731
1735
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1732
1736
db_options|=HA_OPTION_PACK_RECORD;
1733
1737
alias= table_case_name(create_info, table_name);
1734
if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1738
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
1735
1739
create_info->db_type)))
1737
1741
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1741
set_table_default_charset(session, create_info, (char*) db);
1745
set_table_default_charset(thd, create_info, (char*) db);
1743
if (mysql_prepare_create_table(session, create_info, alter_info,
1747
if (mysql_prepare_create_table(thd, create_info, alter_info,
1744
1748
internal_tmp_table,
1745
1749
&db_options, file,
1746
1750
&key_info_buffer, &key_count,
1766
path_length= build_table_filename(path, sizeof(path), db, alias, "",
1770
path_length= build_table_filename(path, sizeof(path), db, alias, reg_ext,
1767
1771
internal_tmp_table ? FN_IS_TMP : 0);
1770
1774
/* Check if table already exists */
1771
1775
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
1772
find_temporary_table(session, db, table_name))
1776
find_temporary_table(thd, db, table_name))
1774
1778
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1776
1780
create_info->table_existed= 1; // Mark that table existed
1777
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1781
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1778
1782
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1860
1864
#endif /* HAVE_READLINK */
1862
1866
if (create_info->data_file_name)
1863
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1867
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1864
1868
"DATA DIRECTORY option ignored");
1865
1869
if (create_info->index_file_name)
1866
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1870
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1867
1871
"INDEX DIRECTORY option ignored");
1868
1872
create_info->data_file_name= create_info->index_file_name= 0;
1870
1874
create_info->table_options=db_options;
1872
if (rea_create_table(session, path, db, table_name,
1876
path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1877
if (rea_create_table(thd, path, db, table_name,
1873
1878
create_info, alter_info->create_list,
1874
key_count, key_info_buffer, file, false))
1879
key_count, key_info_buffer, file))
1875
1880
goto unlock_and_end;
1877
1882
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1879
1884
/* Open table and put in temporary table list */
1880
if (!(open_temporary_table(session, path, db, table_name, 1, OTM_OPEN)))
1885
if (!(open_temporary_table(thd, path, db, table_name, 1, OTM_OPEN)))
1882
(void) rm_temporary_table(create_info->db_type, path);
1887
(void) rm_temporary_table(create_info->db_type, path, false);
1883
1888
goto unlock_and_end;
1885
session->thread_specific_used= true;
1890
thd->thread_specific_used= true;
1893
1898
Otherwise, the statement shall be binlogged.
1895
1900
if (!internal_tmp_table &&
1896
((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1897
write_bin_log(session, true, session->query, session->query_length);
1901
(!thd->current_stmt_binlog_row_based ||
1902
(thd->current_stmt_binlog_row_based &&
1903
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1904
write_bin_log(thd, true, thd->query, thd->query_length);
1899
1906
unlock_and_end:
1901
pthread_mutex_unlock(&LOCK_open);
1907
pthread_mutex_unlock(&LOCK_open);
1904
session->set_proc_info("After create");
1910
thd_proc_info(thd, "After create");
1910
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1916
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1911
1917
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1913
1919
create_info->table_existed= 1; // Mark that table existed
2086
2090
if (lower_case_table_names == 2 && file &&
2087
2091
!(file->ha_table_flags() & HA_FILE_BASED))
2089
strcpy(tmp_name, old_name);
2093
my_stpcpy(tmp_name, old_name);
2090
2094
my_casedn_str(files_charset_info, tmp_name);
2091
2095
build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2092
2096
flags & FN_FROM_IS_TMP);
2093
2097
from_base= lc_from;
2095
strcpy(tmp_name, new_name);
2099
my_stpcpy(tmp_name, new_name);
2096
2100
my_casedn_str(files_charset_info, tmp_name);
2097
2101
build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2098
2102
flags & FN_TO_IS_TMP);
2170
2174
Win32 clients must also have a WRITE LOCK on the table !
2173
void close_cached_table(Session *session, Table *table)
2177
void close_cached_table(THD *thd, Table *table)
2176
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2180
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
2177
2181
/* Close lock if this is not got with LOCK TABLES */
2180
mysql_unlock_tables(session, session->lock);
2181
session->lock=0; // Start locked threads
2184
mysql_unlock_tables(thd, thd->lock);
2185
thd->lock=0; // Start locked threads
2183
2187
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
2184
unlink_open_table(session, table, true);
2188
unlink_open_table(thd, table, true);
2186
2190
/* When lock on LOCK_open is freed other threads can continue */
2187
2191
broadcast_refresh();
2191
static int send_check_errmsg(Session *session, TableList* table,
2195
static int send_check_errmsg(THD *thd, TableList* table,
2192
2196
const char* operator_name, const char* errmsg)
2195
Protocol *protocol= session->protocol;
2199
Protocol *protocol= thd->protocol;
2196
2200
protocol->prepare_for_resend();
2197
2201
protocol->store(table->alias, system_charset_info);
2198
2202
protocol->store((char*) operator_name, system_charset_info);
2199
2203
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2200
2204
protocol->store(errmsg, system_charset_info);
2201
session->clear_error();
2202
2206
if (protocol->write())
2208
static int prepare_for_repair(Session *session, TableList *table_list,
2212
static int prepare_for_repair(THD *thd, TableList *table_list,
2209
2213
HA_CHECK_OPT *check_opt)
2223
2227
char key[MAX_DBKEY_LENGTH];
2224
2228
uint32_t key_length;
2226
key_length= create_table_def_key(session, key, table_list, 0);
2230
key_length= create_table_def_key(thd, key, table_list, 0);
2227
2231
pthread_mutex_lock(&LOCK_open);
2228
if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2232
if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
2231
2235
pthread_mutex_unlock(&LOCK_open);
2232
2236
return(0); // Can't open frm file
2235
if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2239
if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2237
2241
release_table_share(share, RELEASE_NORMAL);
2238
2242
pthread_mutex_unlock(&LOCK_open);
2266
2270
Check if this is a table type that stores index and data separately,
2267
2271
like ISAM or MyISAM. We assume fixed order of engine file name
2268
2272
extentions array. First element of engine file name extentions array
2269
is meta/index file extention. Second element - data file extention.
2273
is meta/index file extention. Second element - data file extention.
2271
2275
ext= table->file->bas_ext();
2272
2276
if (!ext[0] || !ext[1])
2273
2277
goto end; // No data file
2275
2279
// Name of data file
2276
sprintf(from,"%s%s", table->s->normalized_path.str, ext[1]);
2280
strxmov(from, table->s->normalized_path.str, ext[1], NULL);
2277
2281
if (stat(from, &stat_info))
2278
2282
goto end; // Can't use USE_FRM flag
2280
snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
2281
from, (unsigned long)current_pid, session->thread_id);
2284
snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2285
from, current_pid, thd->thread_id);
2283
2287
/* If we could open the table, close it */
2284
2288
if (table_list->table)
2286
2290
pthread_mutex_lock(&LOCK_open);
2287
close_cached_table(session, table);
2291
close_cached_table(thd, table);
2288
2292
pthread_mutex_unlock(&LOCK_open);
2290
if (lock_and_wait_for_table_name(session,table_list))
2294
if (lock_and_wait_for_table_name(thd,table_list))
2295
2299
if (my_rename(from, tmp, MYF(MY_WME)))
2297
2301
pthread_mutex_lock(&LOCK_open);
2298
unlock_table_name(session, table_list);
2302
unlock_table_name(thd, table_list);
2299
2303
pthread_mutex_unlock(&LOCK_open);
2300
error= send_check_errmsg(session, table_list, "repair",
2304
error= send_check_errmsg(thd, table_list, "repair",
2301
2305
"Failed renaming data file");
2304
if (mysql_truncate(session, table_list, 1))
2308
if (mysql_truncate(thd, table_list, 1))
2306
2310
pthread_mutex_lock(&LOCK_open);
2307
unlock_table_name(session, table_list);
2311
unlock_table_name(thd, table_list);
2308
2312
pthread_mutex_unlock(&LOCK_open);
2309
error= send_check_errmsg(session, table_list, "repair",
2313
error= send_check_errmsg(thd, table_list, "repair",
2310
2314
"Failed generating table from .frm file");
2313
2317
if (my_rename(tmp, from, MYF(MY_WME)))
2315
2319
pthread_mutex_lock(&LOCK_open);
2316
unlock_table_name(session, table_list);
2320
unlock_table_name(thd, table_list);
2317
2321
pthread_mutex_unlock(&LOCK_open);
2318
error= send_check_errmsg(session, table_list, "repair",
2322
error= send_check_errmsg(thd, table_list, "repair",
2319
2323
"Failed restoring .MYD file");
2325
2329
to finish the repair in the handler later on.
2327
2331
pthread_mutex_lock(&LOCK_open);
2328
if (reopen_name_locked_table(session, table_list, true))
2332
if (reopen_name_locked_table(thd, table_list, true))
2330
unlock_table_name(session, table_list);
2334
unlock_table_name(thd, table_list);
2331
2335
pthread_mutex_unlock(&LOCK_open);
2332
error= send_check_errmsg(session, table_list, "repair",
2336
error= send_check_errmsg(thd, table_list, "repair",
2333
2337
"Failed to open partially repaired table");
2352
2356
false Message sent to net (admin operation went ok)
2353
true Message should be sent by caller
2357
true Message should be sent by caller
2354
2358
(admin operation or network communication failed)
2356
static bool mysql_admin_table(Session* session, TableList* tables,
2360
static bool mysql_admin_table(THD* thd, TableList* tables,
2357
2361
HA_CHECK_OPT* check_opt,
2358
2362
const char *operator_name,
2359
2363
thr_lock_type lock_type,
2360
2364
bool open_for_modify,
2361
2365
bool no_warnings_for_error,
2362
2366
uint32_t extra_open_options,
2363
int (*prepare_func)(Session *, TableList *,
2367
int (*prepare_func)(THD *, TableList *,
2364
2368
HA_CHECK_OPT *),
2365
int (handler::*operator_func)(Session *,
2369
int (handler::*operator_func)(THD *,
2366
2370
HA_CHECK_OPT *))
2368
2372
TableList *table;
2369
Select_Lex *select= &session->lex->select_lex;
2373
SELECT_LEX *select= &thd->lex->select_lex;
2370
2374
List<Item> field_list;
2372
Protocol *protocol= session->protocol;
2373
LEX *lex= session->lex;
2376
Protocol *protocol= thd->protocol;
2374
2378
int result_code= 0;
2375
2379
const CHARSET_INFO * const cs= system_charset_info;
2377
if (! session->endActiveTransaction())
2381
if (end_active_trans(thd))
2379
2383
field_list.push_back(item = new Item_empty_string("Table",
2380
2384
NAME_CHAR_LEN * 2,
2390
2394
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
2397
mysql_ha_rm_tables(thd, tables, false);
2393
2399
for (table= tables; table; table= table->next_local)
2395
2401
char table_name[NAME_LEN*2+2];
2396
2402
char* db = table->db;
2397
2403
bool fatal_error=0;
2399
sprintf(table_name,"%s.%s",db,table->table_name);
2400
session->open_options|= extra_open_options;
2405
strxmov(table_name, db, ".", table->table_name, NULL);
2406
thd->open_options|= extra_open_options;
2401
2407
table->lock_type= lock_type;
2402
2408
/* open only one table from local list of command */
2416
2422
lex->query_tables= table;
2417
2423
lex->query_tables_last= &table->next_global;
2418
2424
lex->query_tables_own_last= 0;
2419
session->no_warnings_for_error= no_warnings_for_error;
2425
thd->no_warnings_for_error= no_warnings_for_error;
2421
open_and_lock_tables(session, table);
2422
session->no_warnings_for_error= 0;
2427
open_and_lock_tables(thd, table);
2428
thd->no_warnings_for_error= 0;
2423
2429
table->next_global= save_next_global;
2424
2430
table->next_local= save_next_local;
2425
session->open_options&= ~extra_open_options;
2431
thd->open_options&= ~extra_open_options;
2428
2434
if (prepare_func)
2430
switch ((*prepare_func)(session, table, check_opt)) {
2436
switch ((*prepare_func)(thd, table, check_opt)) {
2431
2437
case 1: // error, message written to net
2432
ha_autocommit_or_rollback(session, 1);
2433
session->endTransaction(ROLLBACK);
2434
close_thread_tables(session);
2438
ha_autocommit_or_rollback(thd, 1);
2439
end_trans(thd, ROLLBACK);
2440
close_thread_tables(thd);
2436
2442
case -1: // error, message could be written to net
2437
2443
/* purecov: begin inspected */
2485
2491
if (lock_type == TL_WRITE && table->table->s->version)
2487
2493
pthread_mutex_lock(&LOCK_open);
2488
const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2494
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
2489
2495
"Waiting to get writelock");
2490
mysql_lock_abort(session,table->table, true);
2491
remove_table_from_cache(session, table->table->s->db.str,
2496
mysql_lock_abort(thd,table->table, true);
2497
remove_table_from_cache(thd, table->table->s->db.str,
2492
2498
table->table->s->table_name.str,
2493
2499
RTFC_WAIT_OTHER_THREAD_FLAG |
2494
2500
RTFC_CHECK_KILLED_FLAG);
2495
session->exit_cond(old_message);
2496
if (session->killed)
2501
thd->exit_cond(old_message);
2498
2504
open_for_modify= 0;
2512
2518
/* purecov: end */
2515
if (operator_func == &handler::ha_repair && !(check_opt->use_frm))
2521
if (operator_func == &handler::ha_repair &&
2522
!(check_opt->sql_flags & TT_USEFRM))
2517
2524
if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
2518
2525
(table->table->file->ha_check_for_upgrade(check_opt) ==
2519
2526
HA_ADMIN_NEEDS_ALTER))
2521
ha_autocommit_or_rollback(session, 1);
2522
close_thread_tables(session);
2523
result_code= mysql_recreate_table(session, table);
2528
ha_autocommit_or_rollback(thd, 1);
2529
close_thread_tables(thd);
2530
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2531
result_code= mysql_recreate_table(thd, table);
2532
reenable_binlog(thd);
2525
2534
mysql_recreate_table() can push OK or ERROR.
2526
2535
Clear 'OK' status. If there is an error, keep it:
2527
we will store the error message in a result set row
2536
we will store the error message in a result set row
2528
2537
and then clear.
2530
if (session->main_da.is_ok())
2531
session->main_da.reset_diagnostics_area();
2539
if (thd->main_da.is_ok())
2540
thd->main_da.reset_diagnostics_area();
2532
2541
goto send_result;
2536
result_code = (table->table->file->*operator_func)(session, check_opt);
2545
result_code = (table->table->file->*operator_func)(thd, check_opt);
2540
2549
lex->cleanup_after_one_table_open();
2541
session->clear_error(); // these errors shouldn't get client
2550
thd->clear_error(); // these errors shouldn't get client
2543
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2552
List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
2544
2553
DRIZZLE_ERROR *err;
2545
2554
while ((err= it++))
2616
2635
"try with alter", so here we close the table, do an ALTER Table,
2617
2636
reopen the table and do ha_innobase::analyze() on it.
2619
ha_autocommit_or_rollback(session, 0);
2620
close_thread_tables(session);
2638
ha_autocommit_or_rollback(thd, 0);
2639
close_thread_tables(thd);
2621
2640
TableList *save_next_local= table->next_local,
2622
2641
*save_next_global= table->next_global;
2623
2642
table->next_local= table->next_global= 0;
2624
result_code= mysql_recreate_table(session, table);
2643
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
2644
result_code= mysql_recreate_table(thd, table);
2645
reenable_binlog(thd);
2626
2647
mysql_recreate_table() can push OK or ERROR.
2627
2648
Clear 'OK' status. If there is an error, keep it:
2628
we will store the error message in a result set row
2649
we will store the error message in a result set row
2629
2650
and then clear.
2631
if (session->main_da.is_ok())
2632
session->main_da.reset_diagnostics_area();
2633
ha_autocommit_or_rollback(session, 0);
2634
close_thread_tables(session);
2652
if (thd->main_da.is_ok())
2653
thd->main_da.reset_diagnostics_area();
2654
ha_autocommit_or_rollback(thd, 0);
2655
close_thread_tables(thd);
2635
2656
if (!result_code) // recreation went ok
2637
if ((table->table= open_ltable(session, table, lock_type, 0)) &&
2638
((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2658
if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
2659
((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
2639
2660
result_code= 0; // analyze went ok
2641
2662
if (result_code) // either mysql_recreate_table or analyze failed
2643
assert(session->is_error());
2644
if (session->is_error())
2664
assert(thd->is_error());
2665
if (thd->is_error())
2646
const char *err_msg= session->main_da.message();
2647
if (!session->drizzleclient_vio_ok())
2667
const char *err_msg= thd->main_da.message();
2649
errmsg_printf(ERRMSG_LVL_ERROR, "%s", err_msg);
2670
sql_print_error(err_msg);
2705
2734
pthread_mutex_lock(&LOCK_open);
2706
remove_table_from_cache(session, table->table->s->db.str,
2735
remove_table_from_cache(thd, table->table->s->db.str,
2707
2736
table->table->s->table_name.str, RTFC_NO_FLAG);
2708
2737
pthread_mutex_unlock(&LOCK_open);
2712
ha_autocommit_or_rollback(session, 0);
2713
session->endTransaction(COMMIT);
2714
close_thread_tables(session);
2741
ha_autocommit_or_rollback(thd, 0);
2742
end_trans(thd, COMMIT);
2743
close_thread_tables(thd);
2715
2744
table->table=0; // For query cache
2716
2745
if (protocol->write())
2724
ha_autocommit_or_rollback(session, 1);
2725
session->endTransaction(ROLLBACK);
2726
close_thread_tables(session); // Shouldn't be needed
2753
ha_autocommit_or_rollback(thd, 1);
2754
end_trans(thd, ROLLBACK);
2755
close_thread_tables(thd); // Shouldn't be needed
2728
2757
table->table=0;
2733
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2762
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
2735
return(mysql_admin_table(session, tables, check_opt,
2736
"repair", TL_WRITE, 1,
2739
&prepare_for_repair,
2740
&handler::ha_repair));
2764
return(mysql_admin_table(thd, tables, check_opt,
2765
"repair", TL_WRITE, 1,
2766
test(check_opt->sql_flags & TT_USEFRM),
2768
&prepare_for_repair,
2769
&handler::ha_repair));
2744
bool mysql_optimize_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2773
bool mysql_optimize_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
2746
return(mysql_admin_table(session, tables, check_opt,
2747
"optimize", TL_WRITE, 1,0,0,0,
2748
&handler::ha_optimize));
2775
return(mysql_admin_table(thd, tables, check_opt,
2776
"optimize", TL_WRITE, 1,0,0,0,
2777
&handler::ha_optimize));
2848
2877
local_create_info.default_table_charset=default_charset_info;
2849
2878
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2850
2879
schema_table->table->use_all_columns();
2851
if (mysql_prepare_alter_table(session, schema_table->table,
2880
if (mysql_prepare_alter_table(thd, schema_table->table,
2852
2881
&local_create_info, &alter_info))
2855
if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2883
if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
2856
2884
tmp_table, &db_options,
2857
2885
schema_table->table->file,
2858
2886
&schema_table->table->s->key_info, &keys, 0))
2861
2888
local_create_info.max_rows= 0;
2862
if (rea_create_table(session, dst_path, "system_tmp", "system_stupid_i_s_fix_nonsense",
2889
if (mysql_create_frm(thd, dst_path, NULL, NULL,
2863
2890
&local_create_info, alter_info.create_list,
2864
2891
keys, schema_table->table->s->key_info,
2865
schema_table->table->file, true))
2892
schema_table->table->file))
2872
2899
Create a table identical to the specified table
2875
2902
mysql_create_like_table()
2876
session Thread object
2877
2904
table Table list element for target table
2878
2905
src_table Table list element for source table
2879
2906
create_info Create info
2904
2931
we ensure that our statement is properly isolated from all concurrent
2905
2932
operations which matter.
2907
if (open_tables(session, &src_table, ¬_used, 0))
2934
if (open_tables(thd, &src_table, ¬_used, 0))
2910
strncpy(src_path, src_table->table->s->path.str, sizeof(src_path));
2937
strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
2913
2940
Check that destination tables does not exist. Note that its name
2914
2941
was already checked when it was added to the table list.
2916
2943
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2918
if (find_temporary_table(session, db, table_name))
2945
if (find_temporary_table(thd, db, table_name))
2919
2946
goto table_exists;
2920
dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2947
dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
2921
2948
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2925
if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2952
if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
2927
2954
if (!name_lock)
2928
2955
goto table_exists;
2929
2956
dst_path_length= build_table_filename(dst_path, sizeof(dst_path),
2930
db, table_name, "", 0);
2931
if (table_proto_exists(dst_path)==EEXIST)
2957
db, table_name, reg_ext, 0);
2958
if (!access(dst_path, F_OK))
2932
2959
goto table_exists;
2948
2975
pthread_mutex_lock(&LOCK_open);
2949
2976
if (src_table->schema_table)
2951
if (mysql_create_like_schema_frm(session, src_table, dst_path, create_info))
2978
if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
2953
2980
pthread_mutex_unlock(&LOCK_open);
2984
else if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
2959
int dfecopyr= copy_table_proto_file(src_path, dst_path);
2963
if (my_errno == ENOENT)
2964
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2966
my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
2967
pthread_mutex_unlock(&LOCK_open);
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);
2974
2996
creation, instead create the table directly (for both normal
2975
2997
and temporary tables).
2978
if (session->variables.keep_files_on_create)
2999
dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm
3000
if (thd->variables.keep_files_on_create)
2979
3001
create_info->options|= HA_CREATE_KEEP_FILES;
2980
err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
3002
err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
2981
3003
pthread_mutex_unlock(&LOCK_open);
2983
3005
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2985
if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3007
if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
2988
3010
(void) rm_temporary_table(create_info->db_type,
3011
dst_path, false); /* purecov: inspected */
2990
3012
goto err; /* purecov: inspected */
3034
3057
table->table= name_lock;
3035
3058
pthread_mutex_lock(&LOCK_open);
3036
if (reopen_name_locked_table(session, table, false))
3059
if (reopen_name_locked_table(thd, table, false))
3038
3061
pthread_mutex_unlock(&LOCK_open);
3041
3064
pthread_mutex_unlock(&LOCK_open);
3043
int result= store_create_info(session, table, &query,
3066
int result= store_create_info(thd, table, &query,
3046
3069
assert(result == 0); // store_create_info() always return 0
3047
write_bin_log(session, true, query.ptr(), query.length());
3070
write_bin_log(thd, true, query.ptr(), query.length());
3050
write_bin_log(session, true, session->query, session->query_length);
3073
write_bin_log(thd, true, thd->query, thd->query_length);
3053
3076
Case 3 and 4 does nothing under RBR
3080
write_bin_log(thd, true, thd->query, thd->query_length);
3076
3101
pthread_mutex_lock(&LOCK_open);
3077
unlink_open_table(session, name_lock, false);
3102
unlink_open_table(thd, name_lock, false);
3078
3103
pthread_mutex_unlock(&LOCK_open);
3084
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3109
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
3086
3111
thr_lock_type lock_type = TL_READ_NO_INSERT;
3088
return(mysql_admin_table(session, tables, check_opt,
3113
return(mysql_admin_table(thd, tables, check_opt,
3089
3114
"analyze", lock_type, 1, 0, 0, 0,
3090
3115
&handler::ha_analyze));
3094
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3119
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
3096
3121
thr_lock_type lock_type = TL_READ_NO_INSERT;
3098
return(mysql_admin_table(session, tables, check_opt,
3123
return(mysql_admin_table(thd, tables, check_opt,
3099
3124
"check", lock_type,
3100
3125
0, 0, HA_OPEN_FOR_REPAIR, 0,
3101
3126
&handler::ha_check));
3125
3150
We set this flag so that ha_innobase::open and ::external_lock() do
3126
3151
not complain when we lock the table
3128
session->tablespace_op= true;
3129
if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3153
thd->tablespace_op= true;
3154
if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
3131
session->tablespace_op=false;
3156
thd->tablespace_op=false;
3135
3160
error= table->file->ha_discard_or_import_tablespace(discard);
3137
session->set_proc_info("end");
3162
thd_proc_info(thd, "end");
3142
3167
/* The ALTER Table is always in its own transaction */
3143
error = ha_autocommit_or_rollback(session, 0);
3144
if (! session->endActiveTransaction())
3168
error = ha_autocommit_or_rollback(thd, 0);
3169
if (end_active_trans(thd))
3148
write_bin_log(session, false, session->query, session->query_length);
3173
write_bin_log(thd, false, thd->query, thd->query_length);
3151
ha_autocommit_or_rollback(session, error);
3152
session->tablespace_op=false;
3176
ha_autocommit_or_rollback(thd, error);
3177
thd->tablespace_op=false;
3154
3179
if (error == 0)
3160
3185
table->file->print_error(error, MYF(0));
3718
3751
char tmp_name[80];
3719
3752
char path[FN_REFLEN];
3721
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
3722
TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3754
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3755
tmp_file_prefix, current_pid, thd->thread_id);
3723
3756
/* Safety fix for InnoDB */
3724
3757
if (lower_case_table_names)
3725
3758
my_casedn_str(files_charset_info, tmp_name);
3726
3759
altered_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
3728
if ((error= create_temporary_table(session, table, new_db, tmp_name,
3760
altered_create_info.frm_only= 1;
3761
if ((error= create_temporary_table(thd, table, new_db, tmp_name,
3729
3762
&altered_create_info,
3730
3763
alter_info, db_change)))
3811
3846
and will be renamed to the original table name.
3813
3848
pthread_mutex_lock(&LOCK_open);
3814
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3849
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3815
3850
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3817
close_data_files_and_morph_locks(session,
3852
close_data_files_and_morph_locks(thd,
3818
3853
table->pos_in_table_list->db,
3819
3854
table->pos_in_table_list->table_name);
3820
3855
if (mysql_rename_table(NULL,
4060
4088
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
4064
4092
Check that the DATE/DATETIME not null field we are going to add is
4065
4093
either has a default value or the '0000-00-00' is allowed by the
4067
4095
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
4068
4096
flag to allow ALTER Table only if the table to be altered is empty.
4070
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
4098
if ((def->sql_type == DRIZZLE_TYPE_NEWDATE ||
4071
4099
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
4072
!alter_info->datetime_field &&
4073
!(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4074
session->variables.sql_mode & MODE_NO_ZERO_DATE)
4100
!alter_info->datetime_field &&
4101
!(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
4102
thd->variables.sql_mode & MODE_NO_ZERO_DATE)
4076
alter_info->datetime_field= def;
4077
alter_info->error_if_not_empty= true;
4104
alter_info->datetime_field= def;
4105
alter_info->error_if_not_empty= true;
4079
4107
if (!def->after)
4080
4108
new_create_list.push_back(def);
4335
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4361
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
4336
4362
HA_CREATE_INFO *create_info,
4337
4363
TableList *table_list,
4338
4364
Alter_info *alter_info,
4339
4365
uint32_t order_num, order_st *order, bool ignore)
4341
4367
Table *table, *new_table=0, *name_lock= 0;;
4342
string new_name_str;
4344
4369
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4345
4370
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4346
4371
char path[FN_REFLEN];
4347
4372
ha_rows copied= 0,deleted= 0;
4348
4373
handlerton *old_db_type, *new_db_type, *save_old_db_type;
4350
new_name_buff[0]= '\0';
4374
legacy_db_type table_type;
4352
4376
if (table_list && table_list->schema_table)
4354
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4378
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
4369
4393
build_table_filename(path, sizeof(path), db, table_name, "", 0);
4395
mysql_ha_rm_tables(thd, table_list, false);
4371
4397
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4372
4398
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4373
4399
/* Conditionally writes to binlog. */
4374
return(mysql_discard_or_import_tablespace(session,table_list,
4400
return(mysql_discard_or_import_tablespace(thd,table_list,
4375
4401
alter_info->tablespace_op));
4377
oss << drizzle_data_home << "/" << db << "/" << table_name;
4379
(void) unpack_filename(new_name_buff, oss.str().c_str());
4402
strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db,
4403
"/", table_name, reg_ext, NULL);
4404
(void) unpack_filename(new_name_buff, new_name_buff);
4381
4406
If this is just a rename of a view, short cut to the
4382
4407
following scenario: 1) lock LOCK_open 2) do a RENAME
4390
4415
into the main table list, like open_tables does).
4391
4416
This code is wrong and will be removed, please do not copy.
4418
(void)mysql_frm_type(thd, new_name_buff, &table_type);
4394
if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4420
if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
4396
4422
table->use_all_columns();
4398
4424
/* Check that we are not trying to rename to an existing table */
4401
strcpy(new_name_buff,new_name);
4402
strcpy(new_alias= new_alias_buff, new_name);
4427
my_stpcpy(new_name_buff,new_name);
4428
my_stpcpy(new_alias= new_alias_buff, new_name);
4403
4429
if (lower_case_table_names)
4405
4431
if (lower_case_table_names != 2)
4407
my_casedn_str(files_charset_info, new_name_buff);
4408
new_alias= new_name; // Create lower case table name
4433
my_casedn_str(files_charset_info, new_name_buff);
4434
new_alias= new_name; // Create lower case table name
4410
4436
my_casedn_str(files_charset_info, new_name);
4476
4502
if (create_info->row_type == ROW_TYPE_NOT_USED)
4477
4503
create_info->row_type= table->s->row_type;
4479
if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_ALTER_NOT_SUPPORTED) ||
4480
ha_check_storage_engine_flag(new_db_type, HTON_BIT_ALTER_NOT_SUPPORTED))
4505
if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
4506
ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
4482
4508
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
4486
session->set_proc_info("setup");
4512
thd_proc_info(thd, "setup");
4487
4513
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
4488
4514
!table->s->tmp_table) // no need to touch frm
4501
4527
from concurrent DDL statements.
4503
4529
pthread_mutex_lock(&LOCK_open);
4504
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4530
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4505
4531
pthread_mutex_unlock(&LOCK_open);
4506
4532
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4507
4533
/* COND_refresh will be signaled in close_thread_tables() */
4510
4536
pthread_mutex_lock(&LOCK_open);
4511
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4537
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4512
4538
pthread_mutex_unlock(&LOCK_open);
4513
4539
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4514
4540
/* COND_refresh will be signaled in close_thread_tables() */
4612
4638
new_db_type= create_info->db_type;
4614
if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4640
if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
4617
set_table_default_charset(session, create_info, db);
4619
if (session->variables.old_alter_table
4643
set_table_default_charset(thd, create_info, db);
4646
if (thd->variables.old_alter_table
4620
4647
|| (table->s->db_type() != create_info->db_type)
4623
4650
if (alter_info->build_method == HA_BUILD_ONLINE)
4625
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4652
my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4628
4655
alter_info->build_method= HA_BUILD_OFFLINE;
4693
4720
case HA_ALTER_NOT_SUPPORTED:
4694
4721
if (alter_info->build_method == HA_BUILD_ONLINE)
4696
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4697
close_temporary_table(session, altered_table, 1, 1);
4723
my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4724
close_temporary_table(thd, altered_table, 1, 1);
4700
4727
need_copy_table= true;
4702
4729
case HA_ALTER_ERROR:
4704
close_temporary_table(session, altered_table, 1, 1);
4731
close_temporary_table(thd, altered_table, 1, 1);
4745
4772
if (altered_table)
4746
close_temporary_table(session, altered_table, 1, 1);
4773
close_temporary_table(thd, altered_table, 1, 1);
4749
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
4750
(unsigned long)current_pid, session->thread_id);
4776
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4777
current_pid, thd->thread_id);
4751
4778
/* Safety fix for innodb */
4752
4779
if (lower_case_table_names)
4753
4780
my_casedn_str(files_charset_info, tmp_name);
4756
4783
/* Create a temporary table with the new format */
4757
if ((error= create_temporary_table(session, table, new_db, tmp_name,
4758
create_info, alter_info,
4784
if ((error= create_temporary_table(thd, table, new_db, tmp_name,
4785
create_info, alter_info,
4759
4786
!strcmp(db, new_db))))
4768
4795
memset(&tbl, 0, sizeof(tbl));
4769
4796
tbl.db= new_db;
4770
4797
tbl.table_name= tbl.alias= tmp_name;
4771
/* Table is in session->temporary_tables */
4772
new_table= open_table(session, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4798
/* Table is in thd->temporary_tables */
4799
new_table= open_table(thd, &tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
4776
char tmp_path[FN_REFLEN];
4803
char path[FN_REFLEN];
4777
4804
/* table is a normal table: Create temporary table in same directory */
4778
build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, "",
4805
build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4780
4807
/* Open our intermediate table */
4781
new_table=open_temporary_table(session, tmp_path, new_db, tmp_name, 0, OTM_OPEN);
4808
new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
4783
4810
if (!new_table)
4786
4813
/* Copy the data if necessary. */
4787
session->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
4788
session->cuted_fields=0L;
4789
session->set_proc_info("copy to tmp table");
4814
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
4815
thd->cuted_fields=0L;
4816
thd_proc_info(thd, "copy to tmp table");
4790
4817
copied=deleted=0;
4792
4819
We do not copy data for MERGE tables. Only the children have data.
4808
4835
pthread_mutex_lock(&LOCK_open);
4809
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4836
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4810
4837
pthread_mutex_unlock(&LOCK_open);
4811
4838
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4812
4839
alter_info->keys_onoff);
4813
error= ha_autocommit_or_rollback(session, 0);
4814
if (! session->endActiveTransaction())
4840
error= ha_autocommit_or_rollback(thd, 0);
4841
if (end_active_trans(thd))
4817
/* We must not ignore bad input! */;
4818
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
4844
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
4820
4846
if (table->s->tmp_table != NO_TMP_TABLE)
4825
4851
/* Close lock if this is a transactional table */
4828
mysql_unlock_tables(session, session->lock);
4854
mysql_unlock_tables(thd, thd->lock);
4831
4857
/* Remove link to old table and rename the new one */
4832
close_temporary_table(session, table, 1, 1);
4858
close_temporary_table(thd, table, 1, 1);
4833
4859
/* Should pass the 'new_name' as we store table name in the cache */
4834
if (rename_temporary_table(session, new_table, new_db, new_name))
4860
if (rename_temporary_table(thd, new_table, new_db, new_name))
4862
/* We don't replicate alter table statement on temporary tables */
4863
if (!thd->current_stmt_binlog_row_based)
4864
write_bin_log(thd, true, thd->query, thd->query_length);
4836
4865
goto end_temporary;
4869
4898
call to remove name-locks from table cache and list of open table.
4872
session->set_proc_info("rename result table");
4873
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
4874
(unsigned long)current_pid, session->thread_id);
4901
thd_proc_info(thd, "rename result table");
4902
snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
4903
current_pid, thd->thread_id);
4875
4904
if (lower_case_table_names)
4876
4905
my_casedn_str(files_charset_info, old_name);
4878
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
4879
close_data_files_and_morph_locks(session, db, table_name);
4907
wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4908
close_data_files_and_morph_locks(thd, db, table_name);
4882
4911
save_old_db_type= old_db_type;
4920
4949
quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4923
if (session->locked_tables && new_name == table_name && new_db == db)
4952
if (thd->locked_tables && new_name == table_name && new_db == db)
4925
session->in_lock_tables= 1;
4926
error= reopen_tables(session, 1, 1);
4927
session->in_lock_tables= 0;
4954
thd->in_lock_tables= 1;
4955
error= reopen_tables(thd, 1, 1);
4956
thd->in_lock_tables= 0;
4929
4958
goto err_with_placeholders;
4931
4960
pthread_mutex_unlock(&LOCK_open);
4933
session->set_proc_info("end");
4935
write_bin_log(session, true, session->query, session->query_length);
4937
if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
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))
4940
4972
For the alter table to be properly flushed to the logs, we
4941
4973
have to open the new table. If not, we get a problem on server
4942
4974
shutdown. But we do not need to attach MERGE children.
4944
char table_path[FN_REFLEN];
4976
char path[FN_REFLEN];
4945
4977
Table *t_table;
4946
build_table_filename(table_path, sizeof(table_path), new_db, table_name, "", 0);
4947
t_table= open_temporary_table(session, table_path, new_db, tmp_name, false, OTM_OPEN);
4978
build_table_filename(path, sizeof(path), new_db, table_name, "", 0);
4979
t_table= open_temporary_table(thd, path, new_db, tmp_name, false, OTM_OPEN);
4950
4982
intern_close_table(t_table);
4954
errmsg_printf(ERRMSG_LVL_WARN,
4955
_("Could not open table %s.%s after rename\n"),
4986
sql_print_warning(_("Could not open table %s.%s after rename\n"),
4957
4988
ha_flush_logs(old_db_type);
4959
4990
table_list->table=0; // For query cache
4961
if (session->locked_tables && (new_name != table_name || new_db != db))
4992
if (thd->locked_tables && (new_name != table_name || new_db != db))
4964
4995
If are we under LOCK TABLES and did ALTER Table with RENAME we need
4967
4998
LOCK TABLES we can rely on close_thread_tables() doing this job.
4969
5000
pthread_mutex_lock(&LOCK_open);
4970
unlink_open_table(session, table, false);
4971
unlink_open_table(session, name_lock, false);
5001
unlink_open_table(thd, table, false);
5002
unlink_open_table(thd, name_lock, false);
4972
5003
pthread_mutex_unlock(&LOCK_open);
4977
* Field::store() may have called my_error(). If this is
4978
* the case, we must not send an ok packet, since
4979
* Diagnostics_area::is_set() will fail an assert.
4981
if (! session->is_error())
4983
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
4984
(ulong) (copied + deleted), (ulong) deleted,
4985
(ulong) session->cuted_fields);
4986
session->my_ok(copied + deleted, 0L, tmp_name);
4987
session->some_tables_deleted=0;
4992
/* my_error() was called. Return true (which means error...) */
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;
4999
5017
/* close_temporary_table() frees the new_table pointer. */
5000
close_temporary_table(session, new_table, 1, 1);
5018
close_temporary_table(thd, new_table, 1, 1);
5003
5021
quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5027
5045
/* Shouldn't get here. */
5030
bool save_abort_on_warning= session->abort_on_warning;
5031
session->abort_on_warning= true;
5032
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5048
bool save_abort_on_warning= thd->abort_on_warning;
5049
thd->abort_on_warning= true;
5050
make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5033
5051
f_val, strlength(f_val), t_type,
5034
5052
alter_info->datetime_field->field_name);
5035
session->abort_on_warning= save_abort_on_warning;
5053
thd->abort_on_warning= save_abort_on_warning;
5039
5057
pthread_mutex_lock(&LOCK_open);
5040
unlink_open_table(session, name_lock, false);
5058
unlink_open_table(thd, name_lock, false);
5041
5059
pthread_mutex_unlock(&LOCK_open);
5085
5103
Turn off recovery logging since rollback of an alter table is to
5086
5104
delete the new table so there is no need to log the changes to it.
5088
5106
This needs to be done before external_lock
5090
error= ha_enable_transaction(session, false);
5108
error= ha_enable_transaction(thd, false);
5094
5112
if (!(copy= new Copy_field[to->s->fields]))
5095
5113
return(-1); /* purecov: inspected */
5097
if (to->file->ha_external_lock(session, F_WRLCK))
5115
if (to->file->ha_external_lock(thd, F_WRLCK))
5100
5118
/* We need external lock before we can disable/enable keys */
5101
5119
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5103
5121
/* We can abort alter table for any table type */
5104
session->abort_on_warning= !ignore;
5122
thd->abort_on_warning= !ignore;
5106
5124
from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5107
5125
to->file->ha_start_bulk_insert(from->file->stats.records);
5109
save_sql_mode= session->variables.sql_mode;
5127
save_sql_mode= thd->variables.sql_mode;
5111
5129
List_iterator<Create_field> it(create);
5112
5130
Create_field *def;
5131
5149
if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5133
5151
char warn_buff[DRIZZLE_ERRMSG_SIZE];
5134
snprintf(warn_buff, sizeof(warn_buff),
5152
snprintf(warn_buff, sizeof(warn_buff),
5135
5153
_("order_st BY ignored because there is a user-defined clustered "
5136
5154
"index in the table '%-.192s'"),
5137
5155
from->s->table_name.str);
5138
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5156
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5143
from->sort.io_cache= new IO_CACHE;
5144
memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
5161
from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5162
MYF(MY_FAE | MY_ZEROFILL));
5146
5163
memset(&tables, 0, sizeof(tables));
5147
5164
tables.table= from;
5148
5165
tables.alias= tables.table_name= from->s->table_name.str;
5149
5166
tables.db= from->s->db.str;
5152
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
5153
setup_order(session, session->lex->select_lex.ref_pointer_array,
5169
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5170
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
5154
5171
&tables, fields, all_fields, order) ||
5155
5172
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5156
(from->sort.found_records= filesort(session, from, sortorder, length,
5173
(from->sort.found_records= filesort(thd, from, sortorder, length,
5157
5174
(SQL_SELECT *) 0, HA_POS_ERROR,
5158
5175
1, &examined_rows)) ==
5164
5181
/* Tell handler that we have values for all columns in the to table */
5165
5182
to->use_all_columns();
5166
init_read_record(&info, session, from, (SQL_SELECT *) 0, 1,1);
5183
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
5168
5185
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
5169
session->row_count= 0;
5170
5187
restore_record(to, s->default_values); // Create empty record
5171
5188
while (!(error=info.read_record(&info)))
5173
if (session->killed)
5175
session->send_kill_message();
5192
thd->send_kill_message();
5179
session->row_count++;
5180
5197
/* Return error if source table isn't empty. */
5181
5198
if (error_if_not_empty)
5249
5265
Ensure that the new table is saved properly to disk so that we
5250
5266
can do a rename
5252
if (ha_autocommit_or_rollback(session, 0))
5268
if (ha_autocommit_or_rollback(thd, 0))
5254
if (! session->endActiveTransaction())
5270
if (end_active_trans(thd))
5258
session->variables.sql_mode= save_sql_mode;
5259
session->abort_on_warning= 0;
5274
thd->variables.sql_mode= save_sql_mode;
5275
thd->abort_on_warning= 0;
5260
5276
free_io_cache(from);
5261
5277
*copied= found_count;
5262
5278
*deleted=delete_count;
5263
5279
to->file->ha_release_auto_increment();
5264
if (to->file->ha_external_lock(session,F_UNLCK))
5280
if (to->file->ha_external_lock(thd,F_UNLCK))
5266
5282
return(error > 0 ? -1 : 0);
5295
5311
create_info.default_table_charset=default_charset_info;
5296
5312
/* Force alter table to recreate table */
5297
5313
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5298
return(mysql_alter_table(session, NULL, NULL, &create_info,
5314
return(mysql_alter_table(thd, NULL, NULL, &create_info,
5299
5315
table_list, &alter_info, 0,
5300
5316
(order_st *) 0, 0));
5304
bool mysql_checksum_table(Session *session, TableList *tables,
5320
bool mysql_checksum_table(THD *thd, TableList *tables,
5305
5321
HA_CHECK_OPT *check_opt)
5307
5323
TableList *table;
5308
5324
List<Item> field_list;
5310
Protocol *protocol= session->protocol;
5326
Protocol *protocol= thd->protocol;
5312
5328
field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5313
5329
item->maybe_null= 1;
5324
5340
char table_name[NAME_LEN*2+2];
5327
sprintf(table_name,"%s.%s",table->db,table->table_name);
5343
strxmov(table_name, table->db ,".", table->table_name, NULL);
5329
t= table->table= open_n_lock_single_table(session, table, TL_READ);
5330
session->clear_error(); // these errors shouldn't get client
5345
t= table->table= open_n_lock_single_table(thd, table, TL_READ);
5346
thd->clear_error(); // these errors shouldn't get client
5332
5348
protocol->prepare_for_resend();
5333
5349
protocol->store(table_name, system_charset_info);
5399
5415
t->file->ha_rnd_end();
5402
session->clear_error();
5403
close_thread_tables(session);
5419
close_thread_tables(thd);
5404
5420
table->table=0; // For query cache
5406
5422
if (protocol->write())
5414
close_thread_tables(session); // Shouldn't be needed
5430
close_thread_tables(thd); // Shouldn't be needed
5416
5432
table->table=0;
5420
static bool check_engine(Session *session, const char *table_name,
5436
static bool check_engine(THD *thd, const char *table_name,
5421
5437
HA_CREATE_INFO *create_info)
5423
5439
handlerton **new_engine= &create_info->db_type;
5424
5440
handlerton *req_engine= *new_engine;
5425
5441
bool no_substitution= 1;
5426
if (!(*new_engine= ha_checktype(session, ha_legacy_type(req_engine),
5442
if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
5427
5443
no_substitution, 1)))
5430
5446
if (req_engine && req_engine != *new_engine)
5432
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5448
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5433
5449
ER_WARN_USING_OTHER_HANDLER,
5434
5450
ER(ER_WARN_USING_OTHER_HANDLER),
5435
5451
ha_resolve_storage_engine_name(*new_engine),
5438
5454
if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5439
ha_check_storage_engine_flag(*new_engine, HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5455
ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
5441
5457
if (create_info->used_fields & HA_CREATE_USED_ENGINE)