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