110
void write_bin_log(Session *session, const std::string &query)
106
void write_bin_log(Session *session,
112
109
TransactionServices &transaction_services= TransactionServices::singleton();
113
110
transaction_services.rawStatement(session, query);
114
/* Should should be refactored to go away */
115
void write_bin_log_drop_table(Session *session, bool if_exists, const char *db_name, const char *table_name)
117
TransactionServices &transaction_services= TransactionServices::singleton();
121
built_query.append("DROP TABLE IF EXISTS ");
123
built_query.append("DROP TABLE ");
125
built_query.append("`");
126
if (session->db.empty() || strcmp(db_name, session->db.c_str()) != 0)
128
built_query.append(db_name);
129
built_query.append("`.`");
132
built_query.append(table_name);
133
built_query.append("`");
134
transaction_services.rawStatement(session, built_query);
117
138
Execute the drop of a normal or temporary table
149
170
bool foreign_key_error= false;
152
table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
154
if (not drop_temporary && session->lock_table_names_exclusively(tables))
156
table::Cache::singleton().mutex().unlock();
160
/* Don't give warnings for not found errors, as we already generate notes */
161
session->no_warnings_for_error= 1;
163
for (table= tables; table; table= table->next_local)
165
TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
167
error= session->drop_temporary_table(tmp_identifier);
171
// removed temporary table
172
pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
175
If we have the table in the definition cache, we don't have to check the
176
.frm cursor to find if the table is a normal table (not view) and what
180
for (table= tables; table; table= table->next_local)
182
TableIdentifier identifier(table->db, table->table_name);
184
table->db_type= NULL;
186
if ((share= TableShare::getShare(identifier)))
188
table->db_type= share->db_type();
192
if (not drop_temporary && lock_table_names_exclusively(session, tables))
194
pthread_mutex_unlock(&LOCK_open);
198
/* Don't give warnings for not found errors, as we already generate notes */
199
session->no_warnings_for_error= 1;
201
for (table= tables; table; table= table->next_local)
205
error= session->drop_temporary_table(table);
209
// removed temporary table
213
goto err_with_placeholders;
215
// temporary table not found
219
if (drop_temporary == false)
222
abort_locked_tables(session, db, table->table_name);
223
remove_table_from_cache(session, db, table->table_name,
224
RTFC_WAIT_OTHER_THREAD_FLAG |
225
RTFC_CHECK_KILLED_FLAG);
227
If the table was used in lock tables, remember it so that
228
unlock_table_names can free it
230
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
231
table->table= locked_table;
236
goto err_with_placeholders;
239
TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? message::Table::INTERNAL : message::Table::STANDARD);
241
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
243
// Table was not found on disk and table can't be created from engine
245
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
246
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
175
goto err_with_placeholders;
177
// temporary table not found
253
error= plugin::StorageEngine::dropTable(*session, identifier);
255
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
181
if (drop_temporary == false)
184
abort_locked_tables(session, tmp_identifier);
185
table::Cache::singleton().removeTable(session, tmp_identifier,
186
RTFC_WAIT_OTHER_THREAD_FLAG |
187
RTFC_CHECK_KILLED_FLAG);
189
If the table was used in lock tables, remember it so that
190
unlock_table_names can free it
192
if ((locked_table= drop_locked_tables(session, tmp_identifier)))
193
table->table= locked_table;
195
if (session->getKilled())
198
goto err_with_placeholders;
201
TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
203
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
205
// Table was not found on disk and table can't be created from engine
207
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
208
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
209
table->getTableName());
215
error= plugin::StorageEngine::dropTable(*session, identifier);
217
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
220
session->clear_error();
223
if (error == HA_ERR_ROW_IS_REFERENCED)
225
/* the table is referenced by a foreign key constraint */
226
foreign_key_error= true;
230
if (error == 0 || (if_exists && foreign_key_error == false))
232
TransactionServices &transaction_services= TransactionServices::singleton();
233
transaction_services.dropTable(session, string(table->getSchemaName()), string(table->getTableName()), if_exists);
238
if (wrong_tables.length())
239
wrong_tables.append(',');
240
wrong_tables.append(String(table->getTableName(), system_charset_info));
244
It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
247
table::Cache::singleton().mutex().unlock();
258
session->clear_error();
261
if (error == HA_ERR_ROW_IS_REFERENCED)
263
/* the table is referenced by a foreign key constraint */
264
foreign_key_error= true;
268
if (error == 0 || (if_exists && foreign_key_error == false))
270
TransactionServices &transaction_services= TransactionServices::singleton();
271
transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
276
if (wrong_tables.length())
277
wrong_tables.append(',');
278
wrong_tables.append(String(table->table_name,system_charset_info));
282
It's safe to unlock LOCK_open: we have an exclusive lock
285
pthread_mutex_unlock(&LOCK_open);
251
288
if (wrong_tables.length())
340
class typelib_set_member
344
const CHARSET_INFO * const cs;
346
typelib_set_member(const char* value, unsigned int length,
347
const CHARSET_INFO * const charset)
353
static bool operator==(typelib_set_member const& a, typelib_set_member const& b)
355
return (my_strnncoll(a.cs,
356
(const unsigned char*)a.s.c_str(), a.s.length(),
357
(const unsigned char*)b.s.c_str(), b.s.length())==0);
363
class typelib_set_member_hasher
365
boost::hash<string> hasher;
367
std::size_t operator()(const typelib_set_member& t) const
374
398
static bool check_duplicates_in_interval(const char *set_or_name,
375
399
const char *name, TYPELIB *typelib,
376
400
const CHARSET_INFO * const cs,
1423
1430
assert(identifier.getTableName() == table_proto.name());
1424
1431
db_options= create_info->table_options;
1433
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1434
db_options|=HA_OPTION_PACK_RECORD;
1426
1436
set_table_default_charset(create_info, identifier.getSchemaName().c_str());
1428
1438
/* Build a Table object to pass down to the engine, and the do the actual create. */
1429
1439
if (not mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1432
&key_info_buffer, &key_count,
1433
select_field_count))
1442
&key_info_buffer, &key_count,
1443
select_field_count))
1435
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1445
pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1436
1446
error= locked_create_event(session,
1822
1828
/* Close all instances of the table to allow repair to rename files */
1823
if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1829
if (lock_type == TL_WRITE && table->table->s->version)
1825
table::Cache::singleton().mutex().lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1826
const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1827
"Waiting to get writelock");
1828
session->abortLock(table->table);
1829
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1830
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1831
pthread_mutex_lock(&LOCK_open); /* Lock type is TL_WRITE and we lock to repair the table */
1832
const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
1833
"Waiting to get writelock");
1834
mysql_lock_abort(session,table->table);
1835
remove_table_from_cache(session, table->table->s->getSchemaName(),
1836
table->table->s->getTableName(),
1837
RTFC_WAIT_OTHER_THREAD_FLAG |
1838
RTFC_CHECK_KILLED_FLAG);
1831
1839
session->exit_cond(old_message);
1832
if (session->getKilled())
1840
if (session->killed)
1834
1842
open_for_modify= 0;
1962
We have to write the query before we unlock the named table.
1964
Since temporary tables are not replicated under row-based
1965
replication, CREATE TABLE ... LIKE ... needs special
1966
treatement. We have four cases to consider, according to the
1967
following decision table:
1969
==== ========= ========= ==============================
1970
Case Target Source Write to binary log
1971
==== ========= ========= ==============================
1972
1 normal normal Original statement
1973
2 normal temporary Generated statement
1974
3 temporary normal Nothing
1975
4 temporary temporary Nothing
1976
==== ========= ========= ==============================
1978
static bool replicateCreateTableLike(Session *session, TableList *table, Table *name_lock,
1979
bool is_src_table_tmp, bool is_if_not_exists)
1981
if (is_src_table_tmp)
1984
String query(buf, sizeof(buf), system_charset_info);
1985
query.length(0); // Have to zero it since constructor doesn't
1989
Here we open the destination table, on which we already have
1990
name-lock. This is needed for store_create_info() to work.
1991
The table will be closed by unlink_open_table() at the end
1994
table->table= name_lock;
1995
pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
1996
if (session->reopen_name_locked_table(table, false))
1998
pthread_mutex_unlock(&LOCK_open);
2001
pthread_mutex_unlock(&LOCK_open);
2003
int result= store_create_info(table, &query, is_if_not_exists);
2005
assert(result == 0); // store_create_info() always return 0
2006
write_bin_log(session, query.ptr());
2010
write_bin_log(session, session->query.c_str());
1957
2017
Create a new table by copying from source table
1959
2019
Altough exclusive name-lock on target table protects us from concurrent
1960
2020
DML and DDL operations on it we still want to wrap .FRM creation and call
1961
2021
to plugin::StorageEngine::createTable() in critical section protected by
1962
table::Cache::singleton().mutex() in order to provide minimal atomicity against operations which
2022
LOCK_open in order to provide minimal atomicity against operations which
1963
2023
disregard name-locks, like I_S implementation, for example. This is a
1964
2024
temporary and should not be copied. Instead we should fix our code to
1965
2025
always honor name-locks.
1967
Also some engines (e.g. NDB cluster) require that table::Cache::singleton().mutex() should be held
2027
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
1968
2028
during the call to plugin::StorageEngine::createTable().
1969
2029
See bug #28614 for more info.
1971
2031
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
const TableIdentifier &destination_identifier,
1973
const TableIdentifier &src_table,
2032
TableIdentifier &destination_identifier,
2033
TableIdentifier &src_table,
1974
2034
bool is_engine_set)
1976
2036
int protoerr= EEXIST;
1977
2037
message::Table new_proto;
1978
message::table::shared_ptr src_proto;
2038
message::Table src_proto;
1980
2040
protoerr= plugin::StorageEngine::getTableDefinition(session,
1983
new_proto.CopyFrom(*src_proto);
2043
new_proto.CopyFrom(src_proto);
1985
2045
if (destination_identifier.isTmp())
2067
2125
if (session->open_tables_from_list(&src_table, ¬_used))
2070
TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
2071
src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
2128
TableIdentifier src_identifier(src_table->table->s->getSchemaName(),
2129
src_table->table->s->getTableName(), src_table->table->s->tmp_table);
2076
2134
Check that destination tables does not exist. Note that its name
2077
2135
was already checked when it was added to the table list.
2079
For temporary tables we don't aim to grab locks.
2081
2137
bool table_exists= false;
2082
2138
if (destination_identifier.isTmp())
2084
if (session->find_temporary_table(destination_identifier))
2140
if (session->find_temporary_table(db, table_name))
2086
2142
table_exists= true;
2090
bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2091
src_identifier, is_engine_set);
2092
if (not was_created) // This is pretty paranoid, but we assume something might not clean up after itself
2094
(void) session->rm_temporary_table(destination_identifier, true);
2096
else if (not session->open_temporary_table(destination_identifier))
2098
// We created, but we can't open... also, a hack.
2099
(void) session->rm_temporary_table(destination_identifier, true);
2107
else // Standard table which will require locks.
2109
Table *name_lock= 0;
2111
if (session->lock_table_name_if_not_cached(destination_identifier, &name_lock))
2147
if (session->lock_table_name_if_not_cached(db, table_name, &name_lock))
2115
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* unlink open tables for create table like*/
2151
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2116
2152
session->unlink_open_table(name_lock);
2153
pthread_mutex_unlock(&LOCK_open);
2162
2173
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2163
2174
snprintf(warn_buff, sizeof(warn_buff),
2164
ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
2175
ER(ER_TABLE_EXISTS_ERROR), table_name);
2165
2176
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2166
2177
ER_TABLE_EXISTS_ERROR,warn_buff);
2171
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
2182
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2185
else // Otherwise we create the table
2187
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2188
was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2189
src_identifier, is_engine_set);
2190
pthread_mutex_unlock(&LOCK_open);
2192
// So we blew the creation of the table, and we scramble to clean up
2193
// anything that might have been created (read... it is a hack)
2194
if (not was_created)
2196
if (destination_identifier.isTmp())
2198
(void) session->rm_temporary_table(destination_identifier);
2202
quick_rm_table(*session, destination_identifier);
2205
else if (destination_identifier.isTmp() && not session->open_temporary_table(destination_identifier))
2207
// We created, but we can't open... also, a hack.
2208
(void) session->rm_temporary_table(destination_identifier);
2212
if (not destination_identifier.isTmp())
2214
bool rc= replicateCreateTableLike(session, table, name_lock, (src_table->table->s->tmp_table), is_if_not_exists);
2224
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2225
session->unlink_open_table(name_lock);
2226
pthread_mutex_unlock(&LOCK_open);