1954
We have to write the query before we unlock the named table.
1956
Since temporary tables are not replicated under row-based
1957
replication, CREATE TABLE ... LIKE ... needs special
1958
treatement. We have four cases to consider, according to the
1959
following decision table:
1961
==== ========= ========= ==============================
1962
Case Target Source Write to binary log
1963
==== ========= ========= ==============================
1964
1 normal normal Original statement
1965
2 normal temporary Generated statement
1966
3 temporary normal Nothing
1967
4 temporary temporary Nothing
1968
==== ========= ========= ==============================
1970
static bool replicateCreateTableLike(Session *session, TableList *table, Table *name_lock,
1971
bool is_src_table_tmp, bool is_if_not_exists)
1973
if (is_src_table_tmp)
1976
String query(buf, sizeof(buf), system_charset_info);
1977
query.length(0); // Have to zero it since constructor doesn't
1981
Here we open the destination table, on which we already have
1982
name-lock. This is needed for store_create_info() to work.
1983
The table will be closed by unlink_open_table() at the end
1986
table->table= name_lock;
1987
pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
1988
if (session->reopen_name_locked_table(table, false))
1990
pthread_mutex_unlock(&LOCK_open);
1993
pthread_mutex_unlock(&LOCK_open);
1995
int result= store_create_info(table, &query, is_if_not_exists);
1997
assert(result == 0); // store_create_info() always return 0
1998
write_bin_log(session, query.ptr());
2002
write_bin_log(session, session->query.c_str());
2009
Create a new table by copying from source table
2011
Altough exclusive name-lock on target table protects us from concurrent
2012
DML and DDL operations on it we still want to wrap .FRM creation and call
2013
to plugin::StorageEngine::createTable() in critical section protected by
2014
LOCK_open in order to provide minimal atomicity against operations which
2015
disregard name-locks, like I_S implementation, for example. This is a
2016
temporary and should not be copied. Instead we should fix our code to
2017
always honor name-locks.
2019
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2020
during the call to plugin::StorageEngine::createTable().
2021
See bug #28614 for more info.
2023
static bool create_table_wrapper(Session &session, message::Table& create_table_proto,
2024
TableIdentifier &destination_identifier,
2025
TableIdentifier &src_table,
2026
bool lex_identified_temp_table, bool is_engine_set)
2028
int protoerr= EEXIST;
2029
message::Table new_proto;
2030
message::Table src_proto;
2032
protoerr= plugin::StorageEngine::getTableDefinition(session,
2035
new_proto.CopyFrom(src_proto);
2037
if (lex_identified_temp_table)
2039
new_proto.set_type(message::Table::TEMPORARY);
2043
new_proto.set_type(message::Table::STANDARD);
2048
message::Table::StorageEngine *protoengine;
2050
protoengine= new_proto.mutable_engine();
2051
protoengine->set_name(create_table_proto.engine().name());
2054
if (protoerr == EEXIST)
2056
plugin::StorageEngine* engine= plugin::StorageEngine::findByName(session,
2057
new_proto.engine().name());
2059
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
2061
string dst_proto_path(destination_identifier.getPath());
2062
dst_proto_path.append(".dfe");
2064
protoerr= drizzle_write_proto_file(dst_proto_path.c_str(), &new_proto);
2074
if (errno == ENOENT)
2075
my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName());
2077
my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath(), errno);
2083
As mysql_truncate don't work on a new table at this stage of
2084
creation, instead create the table directly (for both normal
2085
and temporary tables).
2087
int err= plugin::StorageEngine::createTable(session,
2088
destination_identifier,
2091
return err ? false : true;
1952
2095
Create a table identical to the specified table
1991
2133
if (session->open_tables_from_list(&src_table, ¬_used))
1994
TableIdentifier destination_identifier(db, table_name, lex_identified_temp_table ? TEMP_TABLE : NO_TMP_TABLE);
2136
TableIdentifier destination_identifier(db, table_name,
2137
lex_identified_temp_table ? TEMP_TABLE : STANDARD_TABLE);
2139
TableIdentifier src_identifier(src_table->table->s->db.str,
2140
src_table->table->s->table_name.str, src_table->table->s->tmp_table);
1997
2145
Check that destination tables does not exist. Note that its name
1998
2146
was already checked when it was added to the table list.
2148
bool table_exists= false;
2000
2149
if (lex_identified_temp_table)
2002
2151
if (session->find_temporary_table(db, table_name))
2007
2158
if (session->lock_table_name_if_not_cached(db, table_name, &name_lock))
2162
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2163
session->unlink_open_table(name_lock);
2164
pthread_mutex_unlock(&LOCK_open);
2009
2170
if (not name_lock)
2012
if (plugin::StorageEngine::doesTableExist(*session, destination_identifier))
2174
else if (plugin::StorageEngine::doesTableExist(*session, destination_identifier))
2017
Create a new table by copying from source table
2019
Altough exclusive name-lock on target table protects us from concurrent
2020
DML and DDL operations on it we still want to wrap .FRM creation and call
2021
to plugin::StorageEngine::createTable() in critical section protected by
2022
LOCK_open in order to provide minimal atomicity against operations which
2023
disregard name-locks, like I_S implementation, for example. This is a
2024
temporary and should not be copied. Instead we should fix our code to
2025
always honor name-locks.
2027
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2028
during the call to plugin::StorageEngine::createTable().
2029
See bug #28614 for more info.
2031
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2033
int protoerr= EEXIST;
2035
TableIdentifier identifier(src_table->table->s->db.str,
2036
src_table->table->s->table_name.str, src_table->table->s->tmp_table);
2037
protoerr= plugin::StorageEngine::getTableDefinition(*session,
2041
message::Table new_proto(src_proto);
2043
if (lex_identified_temp_table)
2182
if (is_if_not_exists)
2045
new_proto.set_type(message::Table::TEMPORARY);
2184
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2185
snprintf(warn_buff, sizeof(warn_buff),
2186
ER(ER_TABLE_EXISTS_ERROR), table_name);
2187
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2188
ER_TABLE_EXISTS_ERROR,warn_buff);
2049
new_proto.set_type(message::Table::STANDARD);
2054
message::Table::StorageEngine *protoengine;
2056
protoengine= new_proto.mutable_engine();
2057
protoengine->set_name(create_table_proto.engine().name());
2060
if (protoerr == EEXIST)
2062
plugin::StorageEngine* engine= plugin::StorageEngine::findByName(*session,
2063
new_proto.engine().name());
2065
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
2067
string dst_proto_path(destination_identifier.getPath());
2068
dst_proto_path.append(".dfe");
2070
protoerr= drizzle_write_proto_file(dst_proto_path.c_str(), &new_proto);
2080
if (errno == ENOENT)
2081
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2083
my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath(), errno);
2084
pthread_mutex_unlock(&LOCK_open);
2089
As mysql_truncate don't work on a new table at this stage of
2090
creation, instead create the table directly (for both normal
2091
and temporary tables).
2093
err= plugin::StorageEngine::createTable(*session,
2094
destination_identifier,
2193
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2097
pthread_mutex_unlock(&LOCK_open);
2099
if (lex_identified_temp_table)
2196
else // Otherwise we create the table
2101
if (err || !session->open_temporary_table(destination_identifier))
2198
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2199
was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2200
src_identifier, lex_identified_temp_table, is_engine_set);
2201
pthread_mutex_unlock(&LOCK_open);
2203
// So we blew the creation of the table, and we scramble to clean up
2204
// anything that might have been created (read... it is a hack)
2205
if (not was_created)
2207
if (lex_identified_temp_table)
2209
(void) session->rm_temporary_table(engine_arg, destination_identifier);
2213
TableIdentifier identifier(db, table_name, STANDARD_TABLE);
2214
quick_rm_table(*session, identifier);
2217
else if (lex_identified_temp_table && not session->open_temporary_table(destination_identifier))
2219
// We created, but we can't open... also, a hack.
2103
2220
(void) session->rm_temporary_table(engine_arg, destination_identifier);
2109
TableIdentifier identifier(db, table_name, NO_TMP_TABLE);
2110
quick_rm_table(*session, identifier);
2116
We have to write the query before we unlock the tables.
2120
Since temporary tables are not replicated under row-based
2121
replication, CREATE TABLE ... LIKE ... needs special
2122
treatement. We have four cases to consider, according to the
2123
following decision table:
2125
==== ========= ========= ==============================
2126
Case Target Source Write to binary log
2127
==== ========= ========= ==============================
2128
1 normal normal Original statement
2129
2 normal temporary Generated statement
2130
3 temporary normal Nothing
2131
4 temporary temporary Nothing
2132
==== ========= ========= ==============================
2134
if (! lex_identified_temp_table)
2136
if (src_table->table->s->tmp_table) // Case 2
2224
if (not lex_identified_temp_table)
2139
String query(buf, sizeof(buf), system_charset_info);
2140
query.length(0); // Have to zero it since constructor doesn't
2144
Here we open the destination table, on which we already have
2145
name-lock. This is needed for store_create_info() to work.
2146
The table will be closed by unlink_open_table() at the end
2149
table->table= name_lock;
2150
pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
2151
if (session->reopen_name_locked_table(table, false))
2153
pthread_mutex_unlock(&LOCK_open);
2156
pthread_mutex_unlock(&LOCK_open);
2158
int result= store_create_info(table, &query, is_if_not_exists);
2160
assert(result == 0); // store_create_info() always return 0
2161
write_bin_log(session, query.ptr());
2226
bool rc= replicateCreateTableLike(session, table, name_lock, (src_table->table->s->tmp_table), is_if_not_exists);
2164
write_bin_log(session, session->query.c_str());
2172
if (is_if_not_exists)
2174
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2175
snprintf(warn_buff, sizeof(warn_buff),
2176
ER(ER_TABLE_EXISTS_ERROR), table_name);
2177
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2178
ER_TABLE_EXISTS_ERROR,warn_buff);
2182
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2187
2236
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2188
2237
session->unlink_open_table(name_lock);
2189
2238
pthread_mutex_unlock(&LOCK_open);