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/replicator.h>
32
extern HASH lock_db_cache;
24
34
int creating_table= 0; // How many mysql_create_table are running
26
const char *primary_key_name="PRIMARY";
37
bool is_primary_key(KEY *key_info)
39
static const char * primary_key_name="PRIMARY";
40
return (strcmp(key_info->name, primary_key_name)==0);
43
const char* is_primary_key_name(const char* key_name)
45
static const char * primary_key_name="PRIMARY";
46
if (strcmp(key_name, primary_key_name)==0)
28
52
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
29
53
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
30
54
static int copy_data_between_tables(Table *from,Table *to,
31
55
List<Create_field> &create, bool ignore,
32
uint order_num, order_st *order,
56
uint32_t order_num, order_st *order,
33
57
ha_rows *copied,ha_rows *deleted,
34
58
enum enum_enable_or_disable keys_onoff,
35
59
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 *);
61
static bool prepare_blob_field(Session *session, Create_field *sql_field);
62
static bool check_engine(Session *, const char *, HA_CREATE_INFO *);
40
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
64
mysql_prepare_create_table(Session *session, HA_CREATE_INFO *create_info,
41
65
Alter_info *alter_info,
44
68
handler *file, KEY **key_info_buffer,
45
uint *key_count, int select_field_count);
69
uint32_t *key_count, int select_field_count);
47
mysql_prepare_alter_table(THD *thd, Table *table,
71
mysql_prepare_alter_table(Session *session, Table *table,
48
72
HA_CREATE_INFO *create_info,
49
73
Alter_info *alter_info);
102
uint tablename_to_filename(const char *from, char *to, uint to_length)
126
uint32_t tablename_to_filename(const char *from, char *to, uint32_t to_length)
128
uint32_t errors, length;
106
130
if (from[0] == '#' && !strncmp(from, MYSQL50_TABLE_NAME_PREFIX,
107
131
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
108
return((uint) (strmake(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
110
(from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
132
return((uint) (strncpy(to, from+MYSQL50_TABLE_NAME_PREFIX_LENGTH,
134
(from + MYSQL50_TABLE_NAME_PREFIX_LENGTH)));
111
135
length= strconvert(system_charset_info, from,
112
136
&my_charset_filename, to, to_length, &errors);
113
137
if (check_if_legal_tablename(to) &&
150
174
build_tmptable_filename() for them.
177
path length on success, 0 on failure
156
uint build_table_filename(char *buff, size_t bufflen, const char *db,
157
const char *table_name, const char *ext, uint flags)
180
uint32_t build_table_filename(char *buff, size_t bufflen, const char *db,
181
const char *table_name, const char *ext, uint32_t flags)
183
std::string table_path;
159
184
char dbbuff[FN_REFLEN];
160
185
char tbbuff[FN_REFLEN];
186
int rootdir_len= strlen(FN_ROOTDIR);
162
188
if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
163
stpncpy(tbbuff, table_name, sizeof(tbbuff));
189
strncpy(tbbuff, table_name, sizeof(tbbuff));
165
VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
167
VOID(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 = 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= stpncpy(pos, FN_ROOTDIR, end - pos);
176
pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
191
tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
193
tablename_to_filename(db, dbbuff, sizeof(dbbuff));
194
table_path= drizzle_data_home;
195
int without_rootdir= table_path.length()-rootdir_len;
197
/* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
198
if (without_rootdir >= 0)
200
char *tmp= (char*)table_path.c_str()+without_rootdir;
201
if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
202
table_path.append(FN_ROOTDIR);
205
table_path.append(dbbuff);
206
table_path.append(FN_ROOTDIR);
177
207
#ifdef USE_SYMDIR
178
unpack_dirname(buff, buff);
181
pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
210
table_path.append(tbbuff);
211
table_path.append(ext);
213
if (bufflen < table_path.length())
216
strcpy(buff, table_path.c_str());
217
return table_path.length();
188
Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
222
Creates path to a file: drizzle_tmpdir/#sql1234_12_1.ext
191
225
build_tmptable_filename()
192
thd The thread handle.
226
session The thread handle.
193
227
buff Where to write result in my_charset_filename.
194
228
bufflen buff size
198
232
Uses current_pid, thread_id, and tmp_table counter to create
199
a file name in mysql_tmpdir.
233
a file name in drizzle_tmpdir.
236
path length on success, 0 on failure
205
uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
239
uint32_t build_tmptable_filename(Session* session, char *buff, size_t bufflen)
242
std::ostringstream path_str, post_tmpdir_str;
208
char *p= 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);
245
path_str << drizzle_tmpdir;
246
post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
247
post_tmpdir_str << session->thread_id << session->tmp_table++ << reg_ext;
248
tmp= post_tmpdir_str.str();
213
250
if (lower_case_table_names)
215
/* Convert all except tmpdir to lower case */
216
my_casedn_str(files_charset_info, p);
219
uint length= unpack_filename(buff, buff);
251
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
255
if (bufflen < path_str.str().length())
258
length= unpack_filename(buff, path_str.str().c_str());
266
session Thread object
227
267
clear_error is clear_error to be called
228
268
query Query to log
229
269
query_length Length of query
438
468
if (!drop_temporary)
440
470
Table *locked_table;
441
abort_locked_tables(thd, db, table->table_name);
442
remove_table_from_cache(thd, db, table->table_name,
471
abort_locked_tables(session, db, table->table_name);
472
remove_table_from_cache(session, db, table->table_name,
443
473
RTFC_WAIT_OTHER_THREAD_FLAG |
444
474
RTFC_CHECK_KILLED_FLAG);
446
476
If the table was used in lock tables, remember it so that
447
477
unlock_table_names can free it
449
if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
479
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
450
480
table->table= locked_table;
455
485
goto err_with_placeholders;
607
bool quick_rm_table(handlerton *base,const char *db,
608
const char *table_name, uint flags)
635
bool quick_rm_table(handlerton *base __attribute__((unused)),const char *db,
636
const char *table_name, uint32_t flags)
610
638
char path[FN_REFLEN];
613
uint path_length= build_table_filename(path, sizeof(path),
641
uint32_t path_length= build_table_filename(path, sizeof(path),
614
642
db, table_name, reg_ext, flags);
615
643
if (my_delete(path,MYF(0)))
616
644
error= 1; /* purecov: inspected */
617
646
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
618
return(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
648
error|= delete_table_proto_file(path);
650
return(ha_delete_table(current_session, path, db, table_name, 0) ||
978
1013
occupied memory at the same time when we free this
979
1014
sql_field -- at the end of execution.
981
interval= sql_field->interval= typelib(thd->mem_root,
1016
interval= sql_field->interval= typelib(session->mem_root,
982
1017
sql_field->interval_list);
983
1018
List_iterator<String> int_it(sql_field->interval_list);
984
1019
String conv, *tmp;
985
1020
char comma_buf[4];
986
int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
1021
int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
1022
(unsigned char*) comma_buf +
988
1023
sizeof(comma_buf));
989
1024
assert(comma_length > 0);
990
for (uint i= 0; (tmp= int_it++); i++)
1025
for (uint32_t i= 0; (tmp= int_it++); i++)
993
1028
if (String::needs_conversion(tmp->length(), tmp->charset(),
997
1032
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
998
interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
1033
interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
1000
1035
interval->type_lengths[i]= conv.length();
1399
1465
if ((length=column->length) > max_key_length ||
1400
1466
length > file->max_key_part_length())
1402
length=min(max_key_length, file->max_key_part_length());
1468
length=cmin(max_key_length, file->max_key_part_length());
1403
1469
if (key->type == Key::MULTIPLE)
1405
1471
/* not a critical problem */
1406
1472
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1407
1473
snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1409
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1475
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1410
1476
ER_TOO_LONG_KEY, warn_buff);
1411
1477
/* Align key length to multibyte char boundary */
1412
1478
length-= length % sql_field->charset->mbmaxlen;
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
1712
mysql_create_table_no_lock()
1713
session Thread object
1685
1715
table_name Table name
1686
1716
create_info Create information (like MAX_ROWS)
1732
if (check_engine(thd, table_name, create_info))
1763
if (check_engine(session, table_name, create_info))
1734
1765
db_options= create_info->table_options;
1735
1766
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1736
1767
db_options|=HA_OPTION_PACK_RECORD;
1737
1768
alias= table_case_name(create_info, table_name);
1738
if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
1769
if (!(file= get_new_handler((TABLE_SHARE*) 0, session->mem_root,
1739
1770
create_info->db_type)))
1741
1772
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(handler));
1745
set_table_default_charset(thd, create_info, (char*) db);
1776
set_table_default_charset(session, create_info, (char*) db);
1747
if (mysql_prepare_create_table(thd, create_info, alter_info,
1778
if (mysql_prepare_create_table(session, create_info, alter_info,
1748
1779
internal_tmp_table,
1749
1780
&db_options, file,
1750
1781
&key_info_buffer, &key_count,
1864
1896
#endif /* HAVE_READLINK */
1866
1898
if (create_info->data_file_name)
1867
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1899
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1868
1900
"DATA DIRECTORY option ignored");
1869
1901
if (create_info->index_file_name)
1870
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1902
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, 0,
1871
1903
"INDEX DIRECTORY option ignored");
1872
1904
create_info->data_file_name= create_info->index_file_name= 0;
1874
1906
create_info->table_options=db_options;
1876
1908
path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
1877
if (rea_create_table(thd, path, db, table_name,
1909
if (rea_create_table(session, path, db, table_name,
1878
1910
create_info, alter_info->create_list,
1879
1911
key_count, key_info_buffer, file))
1880
1912
goto unlock_and_end;
1898
1930
Otherwise, the statement shall be binlogged.
1900
1932
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);
1933
((!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
1934
write_bin_log(session, true, session->query, session->query_length);
1906
1936
unlock_and_end:
1907
VOID(pthread_mutex_unlock(&LOCK_open));
1938
pthread_mutex_unlock(&LOCK_open);
1910
thd_proc_info(thd, "After create");
1941
session->set_proc_info("After create");
1916
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1947
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1917
1948
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1919
1950
create_info->table_existed= 1; // Mark that table existed
1925
1956
Database locking aware wrapper for mysql_create_table_no_lock(),
1928
bool mysql_create_table(THD *thd, const char *db, const char *table_name,
1959
bool mysql_create_table(Session *session, const char *db, const char *table_name,
1929
1960
HA_CREATE_INFO *create_info,
1930
1961
Alter_info *alter_info,
1931
1962
bool internal_tmp_table,
1932
uint select_field_count)
1963
uint32_t select_field_count)
1934
1965
Table *name_lock= 0;
1937
1968
/* Wait for any database locks */
1938
1969
pthread_mutex_lock(&LOCK_lock_db);
1939
while (!thd->killed &&
1940
hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
1970
while (!session->killed &&
1971
hash_search(&lock_db_cache,(unsigned char*) db, strlen(db)))
1942
wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1973
wait_for_condition(session, &LOCK_lock_db, &COND_refresh);
1943
1974
pthread_mutex_lock(&LOCK_lock_db);
1977
if (session->killed)
1948
1979
pthread_mutex_unlock(&LOCK_lock_db);
2017
2048
char buff[MAX_FIELD_NAME],*buff_end;
2019
2050
if (!check_if_keyname_exists(field_name,start,end) &&
2020
my_strcasecmp(system_charset_info,field_name,primary_key_name))
2051
!is_primary_key_name(field_name))
2021
2052
return (char*) field_name; // Use fieldname
2022
buff_end=strmake(buff,field_name, sizeof(buff)-4);
2054
buff_end= strncpy(buff, field_name, sizeof(buff)-4);
2055
buff_end+= strlen(buff);
2025
2058
Only 3 chars + '\0' left, so need to limit to 2 digit
2026
2059
This is ok as we can't have more than 100 keys anyway
2028
for (uint i=2 ; i< 100; i++)
2061
for (uint32_t i=2 ; i< 100; i++)
2030
2063
*buff_end= '_';
2031
2064
int10_to_str(i, buff_end+1, 10);
2090
2123
if (lower_case_table_names == 2 && file &&
2091
2124
!(file->ha_table_flags() & HA_FILE_BASED))
2093
stpcpy(tmp_name, old_name);
2126
strcpy(tmp_name, old_name);
2094
2127
my_casedn_str(files_charset_info, tmp_name);
2095
2128
build_table_filename(lc_from, sizeof(lc_from), old_db, tmp_name, "",
2096
2129
flags & FN_FROM_IS_TMP);
2097
2130
from_base= lc_from;
2099
stpcpy(tmp_name, new_name);
2132
strcpy(tmp_name, new_name);
2100
2133
my_casedn_str(files_charset_info, tmp_name);
2101
2134
build_table_filename(lc_to, sizeof(lc_to), new_db, tmp_name, "",
2102
2135
flags & FN_TO_IS_TMP);
2140
2182
Win32 clients must also have a WRITE LOCK on the table !
2143
void wait_while_table_is_used(THD *thd, Table *table,
2185
void wait_while_table_is_used(Session *session, Table *table,
2144
2186
enum ha_extra_function function)
2147
2189
safe_mutex_assert_owner(&LOCK_open);
2149
VOID(table->file->extra(function));
2191
table->file->extra(function);
2150
2192
/* Mark all tables that are in use as 'old' */
2151
mysql_lock_abort(thd, table, true); /* end threads waiting on lock */
2193
mysql_lock_abort(session, table, true); /* end threads waiting on lock */
2153
2195
/* Wait until all there are no other threads that has this table open */
2154
remove_table_from_cache(thd, table->s->db.str,
2196
remove_table_from_cache(session, table->s->db.str,
2155
2197
table->s->table_name.str,
2156
2198
RTFC_WAIT_OTHER_THREAD_FLAG);
2174
2216
Win32 clients must also have a WRITE LOCK on the table !
2177
void close_cached_table(THD *thd, Table *table)
2219
void close_cached_table(Session *session, Table *table)
2180
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
2222
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
2181
2223
/* Close lock if this is not got with LOCK TABLES */
2184
mysql_unlock_tables(thd, thd->lock);
2185
thd->lock=0; // Start locked threads
2226
mysql_unlock_tables(session, session->lock);
2227
session->lock=0; // Start locked threads
2187
2229
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
2188
unlink_open_table(thd, table, true);
2230
unlink_open_table(session, table, true);
2190
2232
/* When lock on LOCK_open is freed other threads can continue */
2191
2233
broadcast_refresh();
2195
static int send_check_errmsg(THD *thd, TableList* table,
2237
static int send_check_errmsg(Session *session, TableList* table,
2196
2238
const char* operator_name, const char* errmsg)
2199
Protocol *protocol= thd->protocol;
2241
Protocol *protocol= session->protocol;
2200
2242
protocol->prepare_for_resend();
2201
2243
protocol->store(table->alias, system_charset_info);
2202
2244
protocol->store((char*) operator_name, system_charset_info);
2203
2245
protocol->store(STRING_WITH_LEN("error"), system_charset_info);
2204
2246
protocol->store(errmsg, system_charset_info);
2247
session->clear_error();
2206
2248
if (protocol->write())
2212
static int prepare_for_repair(THD *thd, TableList *table_list,
2254
static int prepare_for_repair(Session *session, TableList *table_list,
2213
2255
HA_CHECK_OPT *check_opt)
2225
2267
if (!(table= table_list->table)) /* if open_ltable failed */
2227
2269
char key[MAX_DBKEY_LENGTH];
2270
uint32_t key_length;
2230
key_length= create_table_def_key(thd, key, table_list, 0);
2272
key_length= create_table_def_key(session, key, table_list, 0);
2231
2273
pthread_mutex_lock(&LOCK_open);
2232
if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
2274
if (!(share= (get_table_share(session, table_list, key, key_length, 0,
2235
2277
pthread_mutex_unlock(&LOCK_open);
2236
2278
return(0); // Can't open frm file
2239
if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2281
if (open_table_from_share(session, share, "", 0, 0, 0, &tmp_table, OTM_OPEN))
2241
2283
release_table_share(share, RELEASE_NORMAL);
2242
2284
pthread_mutex_unlock(&LOCK_open);
2270
2312
Check if this is a table type that stores index and data separately,
2271
2313
like ISAM or MyISAM. We assume fixed order of engine file name
2272
2314
extentions array. First element of engine file name extentions array
2273
is meta/index file extention. Second element - data file extention.
2315
is meta/index file extention. Second element - data file extention.
2275
2317
ext= table->file->bas_ext();
2276
2318
if (!ext[0] || !ext[1])
2277
2319
goto end; // No data file
2279
2321
// Name of data file
2280
strxmov(from, table->s->normalized_path.str, ext[1], NullS);
2322
strxmov(from, table->s->normalized_path.str, ext[1], NULL);
2281
2323
if (stat(from, &stat_info))
2282
2324
goto end; // Can't use USE_FRM flag
2284
snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
2285
from, current_pid, thd->thread_id);
2326
snprintf(tmp, sizeof(tmp), "%s-%lx_%"PRIx64,
2327
from, (unsigned long)current_pid, session->thread_id);
2287
2329
/* If we could open the table, close it */
2288
2330
if (table_list->table)
2290
2332
pthread_mutex_lock(&LOCK_open);
2291
close_cached_table(thd, table);
2333
close_cached_table(session, table);
2292
2334
pthread_mutex_unlock(&LOCK_open);
2294
if (lock_and_wait_for_table_name(thd,table_list))
2336
if (lock_and_wait_for_table_name(session,table_list))
2299
2341
if (my_rename(from, tmp, MYF(MY_WME)))
2301
2343
pthread_mutex_lock(&LOCK_open);
2302
unlock_table_name(thd, table_list);
2344
unlock_table_name(session, table_list);
2303
2345
pthread_mutex_unlock(&LOCK_open);
2304
error= send_check_errmsg(thd, table_list, "repair",
2346
error= send_check_errmsg(session, table_list, "repair",
2305
2347
"Failed renaming data file");
2308
if (mysql_truncate(thd, table_list, 1))
2350
if (mysql_truncate(session, table_list, 1))
2310
2352
pthread_mutex_lock(&LOCK_open);
2311
unlock_table_name(thd, table_list);
2353
unlock_table_name(session, table_list);
2312
2354
pthread_mutex_unlock(&LOCK_open);
2313
error= send_check_errmsg(thd, table_list, "repair",
2355
error= send_check_errmsg(session, table_list, "repair",
2314
2356
"Failed generating table from .frm file");
2317
2359
if (my_rename(tmp, from, MYF(MY_WME)))
2319
2361
pthread_mutex_lock(&LOCK_open);
2320
unlock_table_name(thd, table_list);
2362
unlock_table_name(session, table_list);
2321
2363
pthread_mutex_unlock(&LOCK_open);
2322
error= send_check_errmsg(thd, table_list, "repair",
2364
error= send_check_errmsg(session, table_list, "repair",
2323
2365
"Failed restoring .MYD file");
2356
2398
false Message sent to net (admin operation went ok)
2357
true Message should be sent by caller
2399
true Message should be sent by caller
2358
2400
(admin operation or network communication failed)
2360
static bool mysql_admin_table(THD* thd, TableList* tables,
2402
static bool mysql_admin_table(Session* session, TableList* tables,
2361
2403
HA_CHECK_OPT* check_opt,
2362
2404
const char *operator_name,
2363
2405
thr_lock_type lock_type,
2364
2406
bool open_for_modify,
2365
2407
bool no_warnings_for_error,
2366
uint extra_open_options,
2367
int (*prepare_func)(THD *, TableList *,
2408
uint32_t extra_open_options,
2409
int (*prepare_func)(Session *, TableList *,
2368
2410
HA_CHECK_OPT *),
2369
int (handler::*operator_func)(THD *,
2411
int (handler::*operator_func)(Session *,
2370
2412
HA_CHECK_OPT *))
2372
2414
TableList *table;
2373
SELECT_LEX *select= &thd->lex->select_lex;
2415
SELECT_LEX *select= &session->lex->select_lex;
2374
2416
List<Item> field_list;
2376
Protocol *protocol= thd->protocol;
2418
Protocol *protocol= session->protocol;
2419
LEX *lex= session->lex;
2378
2420
int result_code= 0;
2379
2421
const CHARSET_INFO * const cs= system_charset_info;
2381
if (end_active_trans(thd))
2423
if (end_active_trans(session))
2383
2425
field_list.push_back(item = new Item_empty_string("Table",
2384
2426
NAME_CHAR_LEN * 2,
2422
2464
lex->query_tables= table;
2423
2465
lex->query_tables_last= &table->next_global;
2424
2466
lex->query_tables_own_last= 0;
2425
thd->no_warnings_for_error= no_warnings_for_error;
2467
session->no_warnings_for_error= no_warnings_for_error;
2427
open_and_lock_tables(thd, table);
2428
thd->no_warnings_for_error= 0;
2469
open_and_lock_tables(session, table);
2470
session->no_warnings_for_error= 0;
2429
2471
table->next_global= save_next_global;
2430
2472
table->next_local= save_next_local;
2431
thd->open_options&= ~extra_open_options;
2473
session->open_options&= ~extra_open_options;
2434
2476
if (prepare_func)
2436
switch ((*prepare_func)(thd, table, check_opt)) {
2478
switch ((*prepare_func)(session, table, check_opt)) {
2437
2479
case 1: // error, message written to net
2438
ha_autocommit_or_rollback(thd, 1);
2439
end_trans(thd, ROLLBACK);
2440
close_thread_tables(thd);
2480
ha_autocommit_or_rollback(session, 1);
2481
end_trans(session, ROLLBACK);
2482
close_thread_tables(session);
2442
2484
case -1: // error, message could be written to net
2443
2485
/* purecov: begin inspected */
2491
2533
if (lock_type == TL_WRITE && table->table->s->version)
2493
2535
pthread_mutex_lock(&LOCK_open);
2494
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
2536
const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
2495
2537
"Waiting to get writelock");
2496
mysql_lock_abort(thd,table->table, true);
2497
remove_table_from_cache(thd, table->table->s->db.str,
2538
mysql_lock_abort(session,table->table, true);
2539
remove_table_from_cache(session, table->table->s->db.str,
2498
2540
table->table->s->table_name.str,
2499
2541
RTFC_WAIT_OTHER_THREAD_FLAG |
2500
2542
RTFC_CHECK_KILLED_FLAG);
2501
thd->exit_cond(old_message);
2543
session->exit_cond(old_message);
2544
if (session->killed)
2504
2546
open_for_modify= 0;
2525
2567
(table->table->file->ha_check_for_upgrade(check_opt) ==
2526
2568
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);
2570
ha_autocommit_or_rollback(session, 1);
2571
close_thread_tables(session);
2572
tmp_disable_binlog(session); // binlogging is done by caller if wanted
2573
result_code= mysql_recreate_table(session, table);
2574
reenable_binlog(session);
2534
2576
mysql_recreate_table() can push OK or ERROR.
2535
2577
Clear 'OK' status. If there is an error, keep it:
2536
we will store the error message in a result set row
2578
we will store the error message in a result set row
2537
2579
and then clear.
2539
if (thd->main_da.is_ok())
2540
thd->main_da.reset_diagnostics_area();
2581
if (session->main_da.is_ok())
2582
session->main_da.reset_diagnostics_area();
2541
2583
goto send_result;
2545
result_code = (table->table->file->*operator_func)(thd, check_opt);
2587
result_code = (table->table->file->*operator_func)(session, check_opt);
2549
2591
lex->cleanup_after_one_table_open();
2550
thd->clear_error(); // these errors shouldn't get client
2592
session->clear_error(); // these errors shouldn't get client
2552
List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
2594
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
2553
2595
DRIZZLE_ERROR *err;
2554
2596
while ((err= it++))
2635
2677
"try with alter", so here we close the table, do an ALTER Table,
2636
2678
reopen the table and do ha_innobase::analyze() on it.
2638
ha_autocommit_or_rollback(thd, 0);
2639
close_thread_tables(thd);
2680
ha_autocommit_or_rollback(session, 0);
2681
close_thread_tables(session);
2640
2682
TableList *save_next_local= table->next_local,
2641
2683
*save_next_global= table->next_global;
2642
2684
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);
2685
tmp_disable_binlog(session); // binlogging is done by caller if wanted
2686
result_code= mysql_recreate_table(session, table);
2687
reenable_binlog(session);
2647
2689
mysql_recreate_table() can push OK or ERROR.
2648
2690
Clear 'OK' status. If there is an error, keep it:
2649
we will store the error message in a result set row
2691
we will store the error message in a result set row
2650
2692
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);
2694
if (session->main_da.is_ok())
2695
session->main_da.reset_diagnostics_area();
2696
ha_autocommit_or_rollback(session, 0);
2697
close_thread_tables(session);
2656
2698
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))
2700
if ((table->table= open_ltable(session, table, lock_type, 0)) &&
2701
((result_code= table->table->file->ha_analyze(session, check_opt)) > 0))
2660
2702
result_code= 0; // analyze went ok
2662
2704
if (result_code) // either mysql_recreate_table or analyze failed
2664
assert(thd->is_error());
2665
if (thd->is_error())
2706
assert(session->is_error());
2707
if (session->is_error())
2667
const char *err_msg= thd->main_da.message();
2709
const char *err_msg= session->main_da.message();
2710
if (!session->vio_ok())
2670
sql_print_error(err_msg);
2712
sql_print_error("%s",err_msg);
2734
2776
pthread_mutex_lock(&LOCK_open);
2735
remove_table_from_cache(thd, table->table->s->db.str,
2777
remove_table_from_cache(session, table->table->s->db.str,
2736
2778
table->table->s->table_name.str, RTFC_NO_FLAG);
2737
2779
pthread_mutex_unlock(&LOCK_open);
2741
ha_autocommit_or_rollback(thd, 0);
2742
end_trans(thd, COMMIT);
2743
close_thread_tables(thd);
2783
ha_autocommit_or_rollback(session, 0);
2784
end_trans(session, COMMIT);
2785
close_thread_tables(session);
2744
2786
table->table=0; // For query cache
2745
2787
if (protocol->write())
2753
ha_autocommit_or_rollback(thd, 1);
2754
end_trans(thd, ROLLBACK);
2755
close_thread_tables(thd); // Shouldn't be needed
2795
ha_autocommit_or_rollback(session, 1);
2796
end_trans(session, ROLLBACK);
2797
close_thread_tables(session); // Shouldn't be needed
2757
2799
table->table=0;
2762
bool mysql_repair_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
2804
bool mysql_repair_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2764
return(mysql_admin_table(thd, tables, check_opt,
2806
return(mysql_admin_table(session, tables, check_opt,
2765
2807
"repair", TL_WRITE, 1,
2766
2808
test(check_opt->sql_flags & TT_USEFRM),
2767
2809
HA_OPEN_FOR_REPAIR,
2877
2919
local_create_info.default_table_charset=default_charset_info;
2878
2920
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
2879
2921
schema_table->table->use_all_columns();
2880
if (mysql_prepare_alter_table(thd, schema_table->table,
2922
if (mysql_prepare_alter_table(session, schema_table->table,
2881
2923
&local_create_info, &alter_info))
2883
if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
2925
if (mysql_prepare_create_table(session, &local_create_info, &alter_info,
2884
2926
tmp_table, &db_options,
2885
2927
schema_table->table->file,
2886
2928
&schema_table->table->s->key_info, &keys, 0))
2888
2930
local_create_info.max_rows= 0;
2889
if (mysql_create_frm(thd, dst_path, NullS, NullS,
2931
if (mysql_create_frm(session, dst_path, NULL, NULL,
2890
2932
&local_create_info, alter_info.create_list,
2891
2933
keys, schema_table->table->s->key_info,
2892
2934
schema_table->table->file))
2931
2973
we ensure that our statement is properly isolated from all concurrent
2932
2974
operations which matter.
2934
if (open_tables(thd, &src_table, ¬_used, 0))
2976
if (open_tables(session, &src_table, ¬_used, 0))
2937
strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
2979
strxmov(src_path, src_table->table->s->path.str, reg_ext, NULL);
2940
2982
Check that destination tables does not exist. Note that its name
2941
2983
was already checked when it was added to the table list.
2943
2985
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2945
if (find_temporary_table(thd, db, table_name))
2987
if (find_temporary_table(session, db, table_name))
2946
2988
goto table_exists;
2947
dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
2989
dst_path_length= build_tmptable_filename(session, dst_path, sizeof(dst_path));
2948
2990
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
2952
if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
2994
if (lock_table_name_if_not_cached(session, db, table_name, &name_lock))
2954
2996
if (!name_lock)
2955
2997
goto table_exists;
2997
3039
and temporary tables).
2999
3041
dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm
3000
if (thd->variables.keep_files_on_create)
3042
if (session->variables.keep_files_on_create)
3001
3043
create_info->options|= HA_CREATE_KEEP_FILES;
3002
err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
3003
VOID(pthread_mutex_unlock(&LOCK_open));
3044
err= ha_create_table(session, dst_path, db, table_name, create_info, 1);
3045
pthread_mutex_unlock(&LOCK_open);
3005
3047
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
3007
if (err || !open_temporary_table(thd, dst_path, db, table_name, 1,
3049
if (err || !open_temporary_table(session, dst_path, db, table_name, 1,
3010
3052
(void) rm_temporary_table(create_info->db_type,
3011
dst_path, false); /* purecov: inspected */
3012
3054
goto err; /* purecov: inspected */
3055
3096
of this function.
3057
3098
table->table= name_lock;
3058
VOID(pthread_mutex_lock(&LOCK_open));
3059
if (reopen_name_locked_table(thd, table, false))
3099
pthread_mutex_lock(&LOCK_open);
3100
if (reopen_name_locked_table(session, table, false))
3061
VOID(pthread_mutex_unlock(&LOCK_open));
3102
pthread_mutex_unlock(&LOCK_open);
3064
VOID(pthread_mutex_unlock(&LOCK_open));
3105
pthread_mutex_unlock(&LOCK_open);
3066
int result= store_create_info(thd, table, &query,
3107
int result= store_create_info(session, table, &query,
3069
3110
assert(result == 0); // store_create_info() always return 0
3070
write_bin_log(thd, true, query.ptr(), query.length());
3111
write_bin_log(session, true, query.ptr(), query.length());
3073
write_bin_log(thd, true, thd->query, thd->query_length);
3114
write_bin_log(session, true, session->query, session->query_length);
3076
3117
Case 3 and 4 does nothing under RBR
3080
write_bin_log(thd, true, thd->query, thd->query_length);
3101
3140
pthread_mutex_lock(&LOCK_open);
3102
unlink_open_table(thd, name_lock, false);
3141
unlink_open_table(session, name_lock, false);
3103
3142
pthread_mutex_unlock(&LOCK_open);
3109
bool mysql_analyze_table(THD* thd, TableList* tables, HA_CHECK_OPT* check_opt)
3148
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
3111
3150
thr_lock_type lock_type = TL_READ_NO_INSERT;
3113
return(mysql_admin_table(thd, tables, check_opt,
3152
return(mysql_admin_table(session, tables, check_opt,
3114
3153
"analyze", lock_type, 1, 0, 0, 0,
3115
3154
&handler::ha_analyze));
3119
bool mysql_check_table(THD* thd, TableList* tables,HA_CHECK_OPT* check_opt)
3158
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
3121
3160
thr_lock_type lock_type = TL_READ_NO_INSERT;
3123
return(mysql_admin_table(thd, tables, check_opt,
3162
return(mysql_admin_table(session, tables, check_opt,
3124
3163
"check", lock_type,
3125
3164
0, 0, HA_OPEN_FOR_REPAIR, 0,
3126
3165
&handler::ha_check));
3150
3189
We set this flag so that ha_innobase::open and ::external_lock() do
3151
3190
not complain when we lock the table
3153
thd->tablespace_op= true;
3154
if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
3192
session->tablespace_op= true;
3193
if (!(table=open_ltable(session, table_list, TL_WRITE, 0)))
3156
thd->tablespace_op=false;
3195
session->tablespace_op=false;
3160
3199
error= table->file->ha_discard_or_import_tablespace(discard);
3162
thd_proc_info(thd, "end");
3201
session->set_proc_info("end");
3167
3206
/* The ALTER Table is always in its own transaction */
3168
error = ha_autocommit_or_rollback(thd, 0);
3169
if (end_active_trans(thd))
3207
error = ha_autocommit_or_rollback(session, 0);
3208
if (end_active_trans(session))
3173
write_bin_log(thd, false, thd->query, thd->query_length);
3212
write_bin_log(session, false, session->query, session->query_length);
3176
ha_autocommit_or_rollback(thd, error);
3177
thd->tablespace_op=false;
3215
ha_autocommit_or_rollback(session, error);
3216
session->tablespace_op=false;
3179
3218
if (error == 0)
3185
3224
table->file->print_error(error, MYF(0));
3751
3784
char tmp_name[80];
3752
3785
char path[FN_REFLEN];
3754
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx",
3755
tmp_file_prefix, current_pid, thd->thread_id);
3787
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64,
3788
TMP_FILE_PREFIX, (unsigned long)current_pid, session->thread_id);
3756
3789
/* Safety fix for InnoDB */
3757
3790
if (lower_case_table_names)
3758
3791
my_casedn_str(files_charset_info, tmp_name);
3759
3792
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,
3794
if ((error= create_temporary_table(session, table, new_db, tmp_name,
3762
3795
&altered_create_info,
3763
3796
alter_info, db_change)))
3845
3878
The final .frm file is already created as a temporary file
3846
3879
and will be renamed to the original table name.
3848
VOID(pthread_mutex_lock(&LOCK_open));
3849
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
3881
pthread_mutex_lock(&LOCK_open);
3882
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
3850
3883
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
3852
close_data_files_and_morph_locks(thd,
3885
close_data_files_and_morph_locks(session,
3853
3886
table->pos_in_table_list->db,
3854
3887
table->pos_in_table_list->table_name);
3855
3888
if (mysql_rename_table(NULL,
4363
bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
4403
bool mysql_alter_table(Session *session,char *new_db, char *new_name,
4364
4404
HA_CREATE_INFO *create_info,
4365
4405
TableList *table_list,
4366
4406
Alter_info *alter_info,
4367
uint order_num, order_st *order, bool ignore)
4407
uint32_t order_num, order_st *order, bool ignore)
4369
4409
Table *table, *new_table=0, *name_lock= 0;;
4410
std::string new_name_str;
4371
4412
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
4372
4413
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
4373
4414
char path[FN_REFLEN];
4374
4415
ha_rows copied= 0,deleted= 0;
4375
4416
handlerton *old_db_type, *new_db_type, *save_old_db_type;
4376
legacy_db_type table_type;
4418
new_name_buff[0]= '\0';
4378
4420
if (table_list && table_list->schema_table)
4380
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
4422
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
4395
4437
build_table_filename(path, sizeof(path), db, table_name, "", 0);
4397
mysql_ha_rm_tables(thd, table_list, false);
4439
mysql_ha_rm_tables(session, table_list, false);
4399
4441
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
4400
4442
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
4401
4443
/* Conditionally writes to binlog. */
4402
return(mysql_discard_or_import_tablespace(thd,table_list,
4444
return(mysql_discard_or_import_tablespace(session,table_list,
4403
4445
alter_info->tablespace_op));
4404
strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db,
4405
"/", table_name, reg_ext, NullS);
4406
(void) unpack_filename(new_name_buff, new_name_buff);
4446
std::ostringstream oss;
4447
oss << drizzle_data_home << "/" << db << "/" << table_name << reg_ext;
4449
(void) unpack_filename(new_name_buff, oss.str().c_str());
4408
4451
If this is just a rename of a view, short cut to the
4409
4452
following scenario: 1) lock LOCK_open 2) do a RENAME
4417
4460
into the main table list, like open_tables does).
4418
4461
This code is wrong and will be removed, please do not copy.
4420
(void)mysql_frm_type(thd, new_name_buff, &table_type);
4422
if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
4464
if (!(table= open_n_lock_single_table(session, table_list, TL_WRITE_ALLOW_READ)))
4424
4466
table->use_all_columns();
4426
4468
/* Check that we are not trying to rename to an existing table */
4429
stpcpy(new_name_buff,new_name);
4430
stpcpy(new_alias= new_alias_buff, new_name);
4471
strcpy(new_name_buff,new_name);
4472
strcpy(new_alias= new_alias_buff, new_name);
4431
4473
if (lower_case_table_names)
4433
4475
if (lower_case_table_names != 2)
4435
my_casedn_str(files_charset_info, new_name_buff);
4436
new_alias= new_name; // Create lower case table name
4477
my_casedn_str(files_charset_info, new_name_buff);
4478
new_alias= new_name; // Create lower case table name
4438
4480
my_casedn_str(files_charset_info, new_name);
4528
4570
while the fact that the table is still open gives us protection
4529
4571
from concurrent DDL statements.
4531
VOID(pthread_mutex_lock(&LOCK_open));
4532
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4533
VOID(pthread_mutex_unlock(&LOCK_open));
4573
pthread_mutex_lock(&LOCK_open);
4574
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4575
pthread_mutex_unlock(&LOCK_open);
4534
4576
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4535
4577
/* COND_refresh will be signaled in close_thread_tables() */
4538
VOID(pthread_mutex_lock(&LOCK_open));
4539
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4540
VOID(pthread_mutex_unlock(&LOCK_open));
4580
pthread_mutex_lock(&LOCK_open);
4581
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4582
pthread_mutex_unlock(&LOCK_open);
4541
4583
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
4542
4584
/* COND_refresh will be signaled in close_thread_tables() */
4640
4682
new_db_type= create_info->db_type;
4642
if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
4684
if (mysql_prepare_alter_table(session, table, create_info, alter_info))
4645
set_table_default_charset(thd, create_info, db);
4648
if (thd->variables.old_alter_table
4687
set_table_default_charset(session, create_info, db);
4690
if (session->variables.old_alter_table
4649
4691
|| (table->s->db_type() != create_info->db_type)
4652
4694
if (alter_info->build_method == HA_BUILD_ONLINE)
4654
my_error(ER_NOT_SUPPORTED_YET, MYF(0), thd->query);
4696
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query);
4657
4699
alter_info->build_method= HA_BUILD_OFFLINE;
4774
4816
if (altered_table)
4775
close_temporary_table(thd, altered_table, 1, 1);
4817
close_temporary_table(session, altered_table, 1, 1);
4778
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
4779
current_pid, thd->thread_id);
4820
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX,
4821
(unsigned long)current_pid, session->thread_id);
4780
4822
/* Safety fix for innodb */
4781
4823
if (lower_case_table_names)
4782
4824
my_casedn_str(files_charset_info, tmp_name);
4785
4827
/* Create a temporary table with the new format */
4786
if ((error= create_temporary_table(thd, table, new_db, tmp_name,
4787
create_info, alter_info,
4828
if ((error= create_temporary_table(session, table, new_db, tmp_name,
4829
create_info, alter_info,
4788
4830
!strcmp(db, new_db))))
4807
4849
build_table_filename(path, sizeof(path), new_db, tmp_name, "",
4809
4851
/* Open our intermediate table */
4810
new_table=open_temporary_table(thd, path, new_db, tmp_name, 0, OTM_OPEN);
4852
new_table=open_temporary_table(session, path, new_db, tmp_name, 0, OTM_OPEN);
4812
4854
if (!new_table)
4815
4857
/* Copy the data if necessary. */
4816
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
4817
thd->cuted_fields=0L;
4818
thd_proc_info(thd, "copy to tmp table");
4858
session->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
4859
session->cuted_fields=0L;
4860
session->set_proc_info("copy to tmp table");
4819
4861
copied=deleted=0;
4821
4863
We do not copy data for MERGE tables. Only the children have data.
4837
VOID(pthread_mutex_lock(&LOCK_open));
4838
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
4839
VOID(pthread_mutex_unlock(&LOCK_open));
4879
pthread_mutex_lock(&LOCK_open);
4880
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
4881
pthread_mutex_unlock(&LOCK_open);
4840
4882
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
4841
4883
alter_info->keys_onoff);
4842
error= ha_autocommit_or_rollback(thd, 0);
4843
if (end_active_trans(thd))
4884
error= ha_autocommit_or_rollback(session, 0);
4885
if (end_active_trans(session))
4846
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
4888
session->count_cuted_fields= CHECK_FIELD_IGNORE;
4848
4890
if (table->s->tmp_table != NO_TMP_TABLE)
4853
4895
/* Close lock if this is a transactional table */
4856
mysql_unlock_tables(thd, thd->lock);
4898
mysql_unlock_tables(session, session->lock);
4859
4901
/* Remove link to old table and rename the new one */
4860
close_temporary_table(thd, table, 1, 1);
4902
close_temporary_table(session, table, 1, 1);
4861
4903
/* Should pass the 'new_name' as we store table name in the cache */
4862
if (rename_temporary_table(thd, new_table, new_db, new_name))
4904
if (rename_temporary_table(session, new_table, new_db, new_name))
4864
/* We don't replicate alter table statement on temporary tables */
4865
if (!thd->current_stmt_binlog_row_based)
4866
write_bin_log(thd, true, thd->query, thd->query_length);
4867
4906
goto end_temporary;
4900
4939
call to remove name-locks from table cache and list of open table.
4903
thd_proc_info(thd, "rename result table");
4904
snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
4905
current_pid, thd->thread_id);
4942
session->set_proc_info("rename result table");
4943
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX,
4944
(unsigned long)current_pid, session->thread_id);
4906
4945
if (lower_case_table_names)
4907
4946
my_casedn_str(files_charset_info, old_name);
4909
wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
4910
close_data_files_and_morph_locks(thd, db, table_name);
4948
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
4949
close_data_files_and_morph_locks(session, db, table_name);
4913
4952
save_old_db_type= old_db_type;
4932
VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4971
quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4934
4973
else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
4935
4974
new_alias, FN_FROM_IS_TMP) || ((new_name != table_name || new_db != db) && 0))
4937
4976
/* Try to get everything back. */
4939
VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
4940
VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
4941
VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
4978
quick_rm_table(new_db_type,new_db,new_alias, 0);
4979
quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
4980
mysql_rename_table(old_db_type, db, old_name, db, alias,
4948
4987
goto err_with_placeholders;
4951
VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
4990
quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
4954
if (thd->locked_tables && new_name == table_name && new_db == db)
4993
if (session->locked_tables && new_name == table_name && new_db == db)
4956
thd->in_lock_tables= 1;
4957
error= reopen_tables(thd, 1, 1);
4958
thd->in_lock_tables= 0;
4995
session->in_lock_tables= 1;
4996
error= reopen_tables(session, 1, 1);
4997
session->in_lock_tables= 0;
4960
4999
goto err_with_placeholders;
4962
VOID(pthread_mutex_unlock(&LOCK_open));
4964
thd_proc_info(thd, "end");
4966
ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
4967
thd->query, thd->query_length,
4970
assert(!(mysql_bin_log.is_open() &&
4971
thd->current_stmt_binlog_row_based &&
5001
pthread_mutex_unlock(&LOCK_open);
5003
session->set_proc_info("end");
5005
assert(!(drizzle_bin_log.is_open() &&
4972
5006
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
4973
write_bin_log(thd, true, thd->query, thd->query_length);
5007
write_bin_log(session, true, session->query, session->query_length);
4975
if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
5009
if (ha_check_storage_engine_flag(old_db_type, HTON_BIT_FLUSH_AFTER_RENAME))
4978
5012
For the alter table to be properly flushed to the logs, we
5004
5038
LOCK TABLES we can rely on close_thread_tables() doing this job.
5006
5040
pthread_mutex_lock(&LOCK_open);
5007
unlink_open_table(thd, table, false);
5008
unlink_open_table(thd, name_lock, false);
5041
unlink_open_table(session, table, false);
5042
unlink_open_table(session, name_lock, false);
5009
5043
pthread_mutex_unlock(&LOCK_open);
5013
5047
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
5014
5048
(ulong) (copied + deleted), (ulong) deleted,
5015
(ulong) thd->cuted_fields);
5016
my_ok(thd, copied + deleted, 0L, tmp_name);
5017
thd->some_tables_deleted=0;
5049
(ulong) session->cuted_fields);
5050
my_ok(session, copied + deleted, 0L, tmp_name);
5051
session->some_tables_deleted=0;
5023
5057
/* close_temporary_table() frees the new_table pointer. */
5024
close_temporary_table(thd, new_table, 1, 1);
5058
close_temporary_table(session, new_table, 1, 1);
5027
VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
5061
quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
5051
5085
/* Shouldn't get here. */
5054
bool save_abort_on_warning= thd->abort_on_warning;
5055
thd->abort_on_warning= true;
5056
make_truncated_value_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5088
bool save_abort_on_warning= session->abort_on_warning;
5089
session->abort_on_warning= true;
5090
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5057
5091
f_val, strlength(f_val), t_type,
5058
5092
alter_info->datetime_field->field_name);
5059
thd->abort_on_warning= save_abort_on_warning;
5093
session->abort_on_warning= save_abort_on_warning;
5063
5097
pthread_mutex_lock(&LOCK_open);
5064
unlink_open_table(thd, name_lock, false);
5098
unlink_open_table(session, name_lock, false);
5065
5099
pthread_mutex_unlock(&LOCK_open);
5109
5143
Turn off recovery logging since rollback of an alter table is to
5110
5144
delete the new table so there is no need to log the changes to it.
5112
5146
This needs to be done before external_lock
5114
error= ha_enable_transaction(thd, false);
5148
error= ha_enable_transaction(session, false);
5118
5152
if (!(copy= new Copy_field[to->s->fields]))
5119
5153
return(-1); /* purecov: inspected */
5121
if (to->file->ha_external_lock(thd, F_WRLCK))
5155
if (to->file->ha_external_lock(session, F_WRLCK))
5124
5158
/* We need external lock before we can disable/enable keys */
5125
5159
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
5127
5161
/* We can abort alter table for any table type */
5128
thd->abort_on_warning= !ignore;
5162
session->abort_on_warning= !ignore;
5130
5164
from->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
5131
5165
to->file->ha_start_bulk_insert(from->file->stats.records);
5133
save_sql_mode= thd->variables.sql_mode;
5167
save_sql_mode= session->variables.sql_mode;
5135
5169
List_iterator<Create_field> it(create);
5136
5170
Create_field *def;
5155
5189
if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
5157
5191
char warn_buff[DRIZZLE_ERRMSG_SIZE];
5158
snprintf(warn_buff, sizeof(warn_buff),
5192
snprintf(warn_buff, sizeof(warn_buff),
5159
5193
_("order_st BY ignored because there is a user-defined clustered "
5160
5194
"index in the table '%-.192s'"),
5161
5195
from->s->table_name.str);
5162
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5196
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
5167
from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
5168
MYF(MY_FAE | MY_ZEROFILL));
5201
from->sort.io_cache=(IO_CACHE*) malloc(sizeof(IO_CACHE));
5202
memset(from->sort.io_cache, 0, sizeof(IO_CACHE));
5169
5204
memset(&tables, 0, sizeof(tables));
5170
5205
tables.table= from;
5171
5206
tables.alias= tables.table_name= from->s->table_name.str;
5172
5207
tables.db= from->s->db.str;
5175
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
5176
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
5210
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
5211
setup_order(session, session->lex->select_lex.ref_pointer_array,
5177
5212
&tables, fields, all_fields, order) ||
5178
5213
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
5179
(from->sort.found_records= filesort(thd, from, sortorder, length,
5214
(from->sort.found_records= filesort(session, from, sortorder, length,
5180
5215
(SQL_SELECT *) 0, HA_POS_ERROR,
5181
5216
1, &examined_rows)) ==
5317
5353
create_info.default_table_charset=default_charset_info;
5318
5354
/* Force alter table to recreate table */
5319
5355
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
5320
return(mysql_alter_table(thd, NullS, NullS, &create_info,
5356
return(mysql_alter_table(session, NULL, NULL, &create_info,
5321
5357
table_list, &alter_info, 0,
5322
5358
(order_st *) 0, 0));
5326
bool mysql_checksum_table(THD *thd, TableList *tables,
5362
bool mysql_checksum_table(Session *session, TableList *tables,
5327
5363
HA_CHECK_OPT *check_opt)
5329
5365
TableList *table;
5330
5366
List<Item> field_list;
5332
Protocol *protocol= thd->protocol;
5368
Protocol *protocol= session->protocol;
5334
5370
field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
5335
5371
item->maybe_null= 1;
5421
5457
t->file->ha_rnd_end();
5425
close_thread_tables(thd);
5460
session->clear_error();
5461
close_thread_tables(session);
5426
5462
table->table=0; // For query cache
5428
5464
if (protocol->write())
5436
close_thread_tables(thd); // Shouldn't be needed
5472
close_thread_tables(session); // Shouldn't be needed
5438
5474
table->table=0;
5442
static bool check_engine(THD *thd, const char *table_name,
5478
static bool check_engine(Session *session, const char *table_name,
5443
5479
HA_CREATE_INFO *create_info)
5445
5481
handlerton **new_engine= &create_info->db_type;
5446
5482
handlerton *req_engine= *new_engine;
5447
5483
bool no_substitution= 1;
5448
if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
5484
if (!(*new_engine= ha_checktype(session, ha_legacy_type(req_engine),
5449
5485
no_substitution, 1)))
5452
5488
if (req_engine && req_engine != *new_engine)
5454
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5490
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
5455
5491
ER_WARN_USING_OTHER_HANDLER,
5456
5492
ER(ER_WARN_USING_OTHER_HANDLER),
5457
5493
ha_resolve_storage_engine_name(*new_engine),
5460
5496
if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
5461
ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
5497
ha_check_storage_engine_flag(*new_engine, HTON_BIT_TEMPORARY_NOT_SUPPORTED))
5463
5499
if (create_info->used_fields & HA_CREATE_USED_ENGINE)