86
85
apply it to the table.
88
87
if (create_info->default_table_charset == NULL)
89
create_info->default_table_charset= get_default_db_collation(db);
93
Translate a cursor name to a table name (WL #1324).
96
filename_to_tablename()
99
to_length The size of the table name buffer.
104
uint32_t filename_to_tablename(const char *from, char *to, uint32_t to_length)
108
if (!memcmp(from, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH))
110
/* Temporary table name. */
111
length= strlen(strncpy(to, from, to_length));
115
for (; *from && length < to_length; length++, from++)
122
/* We've found an escaped char - skip the @ */
125
/* There will be a two-position hex-char version of the char */
126
for (int x=1; x >= 0; x--)
128
if (*from >= '0' && *from <= '9')
129
to[length] += ((*from++ - '0') << (4 * x));
130
else if (*from >= 'a' && *from <= 'f')
131
to[length] += ((*from++ - 'a' + 10) << (4 * x));
133
/* Backup because we advanced extra in the inner loop */
143
Translate a table name to a cursor name (WL #1324).
146
tablename_to_filename()
148
to OUT The cursor name
149
to_length The size of the cursor name buffer.
152
true if errors happen. false on success.
154
bool tablename_to_filename(const char *from, char *to, size_t to_length)
158
for (; *from && length < to_length; length++, from++)
160
if ((*from >= '0' && *from <= '9') ||
161
(*from >= 'A' && *from <= 'Z') ||
162
(*from >= 'a' && *from <= 'z') ||
163
/* OSX defines an extra set of high-bit and multi-byte characters
164
that cannot be used on the filesystem. Instead of trying to sort
165
those out, we'll just escape encode all high-bit-set chars on OSX.
166
It won't really hurt anything - it'll just make some filenames ugly. */
167
#if !defined(TARGET_OS_OSX)
168
((unsigned char)*from >= 128) ||
178
if (length + 3 >= to_length)
181
/* We need to escape this char in a way that can be reversed */
183
to[length++]= hexchars[(*from >> 4) & 15];
184
to[length]= hexchars[(*from) & 15];
187
if (internal::check_if_legal_tablename(to) &&
188
length + 4 < to_length)
190
memcpy(to + length, "@@@", 4);
198
Creates path to a cursor: drizzle_data_dir/db/table.ext
201
build_table_filename()
202
buff Where to write result
203
This may be the same as table_name.
206
table_name Table name
208
flags FN_FROM_IS_TMP or FN_TO_IS_TMP
209
table_name is temporary, do not change.
213
Uses database and table name, and extension to create
214
a cursor name in drizzle_data_dir. Database and table
215
names are converted from system_charset_info into "fscs".
216
Unless flags indicate a temporary table name.
217
'db' is always converted.
218
'ext' is not converted.
220
The conversion suppression is required for ALTER Table. This
221
statement creates intermediate tables. These are regular
222
(non-temporary) tables with a temporary name. Their path names must
223
be derivable from the table name. So we cannot use
224
build_tmptable_filename() for them.
227
path length on success, 0 on failure
230
size_t build_table_filename(char *buff, size_t bufflen, const char *db, const char *table_name, bool is_tmp)
232
char dbbuff[FN_REFLEN];
233
char tbbuff[FN_REFLEN];
234
bool conversion_error= false;
236
memset(tbbuff, 0, sizeof(tbbuff));
237
if (is_tmp) // FN_FROM_IS_TMP | FN_TO_IS_TMP
238
strncpy(tbbuff, table_name, sizeof(tbbuff));
241
conversion_error= tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
242
if (conversion_error)
244
errmsg_printf(ERRMSG_LVL_ERROR,
245
_("Table name cannot be encoded and fit within filesystem "
246
"name length restrictions."));
250
memset(dbbuff, 0, sizeof(dbbuff));
251
conversion_error= tablename_to_filename(db, dbbuff, sizeof(dbbuff));
252
if (conversion_error)
254
errmsg_printf(ERRMSG_LVL_ERROR,
255
_("Schema name cannot be encoded and fit within filesystem "
256
"name length restrictions."));
261
int rootdir_len= strlen(FN_ROOTDIR);
262
string table_path(drizzle_data_home);
263
int without_rootdir= table_path.length()-rootdir_len;
265
/* Don't add FN_ROOTDIR if dirzzle_data_home already includes it */
266
if (without_rootdir >= 0)
268
const char *tmp= table_path.c_str()+without_rootdir;
269
if (memcmp(tmp, FN_ROOTDIR, rootdir_len) != 0)
270
table_path.append(FN_ROOTDIR);
273
table_path.append(dbbuff);
274
table_path.append(FN_ROOTDIR);
275
table_path.append(tbbuff);
277
if (bufflen < table_path.length())
280
strcpy(buff, table_path.c_str());
282
return table_path.length();
287
Creates path to a cursor: drizzle_tmpdir/#sql1234_12_1.ext
290
build_tmptable_filename()
291
session The thread handle.
292
buff Where to write result
297
Uses current_pid, thread_id, and tmp_table counter to create
298
a cursor name in drizzle_tmpdir.
301
path length on success, 0 on failure
304
size_t build_tmptable_filename(char *buff, size_t bufflen)
307
ostringstream path_str, post_tmpdir_str;
310
Session *session= current_session;
312
path_str << drizzle_tmpdir;
313
post_tmpdir_str << "/" << TMP_FILE_PREFIX << current_pid;
314
post_tmpdir_str << session->thread_id << session->tmp_table++;
315
tmp= post_tmpdir_str.str();
317
transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
321
if (bufflen < path_str.str().length())
324
length= internal::unpack_filename(buff, path_str.str().c_str());
88
create_info->default_table_charset= plugin::StorageEngine::getSchemaCollation(db);
1949
We have to write the query before we unlock the named table.
1951
Since temporary tables are not replicated under row-based
1952
replication, CREATE TABLE ... LIKE ... needs special
1953
treatement. We have four cases to consider, according to the
1954
following decision table:
1956
==== ========= ========= ==============================
1957
Case Target Source Write to binary log
1958
==== ========= ========= ==============================
1959
1 normal normal Original statement
1960
2 normal temporary Generated statement
1961
3 temporary normal Nothing
1962
4 temporary temporary Nothing
1963
==== ========= ========= ==============================
1965
static bool replicateCreateTableLike(Session *session, TableList *table, Table *name_lock,
1966
bool is_src_table_tmp, bool is_if_not_exists)
1968
if (is_src_table_tmp)
1971
String query(buf, sizeof(buf), system_charset_info);
1972
query.length(0); // Have to zero it since constructor doesn't
1976
Here we open the destination table, on which we already have
1977
name-lock. This is needed for store_create_info() to work.
1978
The table will be closed by unlink_open_table() at the end
1981
table->table= name_lock;
1982
pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
1983
if (session->reopen_name_locked_table(table, false))
1985
pthread_mutex_unlock(&LOCK_open);
1988
pthread_mutex_unlock(&LOCK_open);
1990
int result= store_create_info(table, &query, is_if_not_exists);
1992
assert(result == 0); // store_create_info() always return 0
1993
write_bin_log(session, query.ptr());
1997
write_bin_log(session, session->query.c_str());
2004
Create a new table by copying from source table
2006
Altough exclusive name-lock on target table protects us from concurrent
2007
DML and DDL operations on it we still want to wrap .FRM creation and call
2008
to plugin::StorageEngine::createTable() in critical section protected by
2009
LOCK_open in order to provide minimal atomicity against operations which
2010
disregard name-locks, like I_S implementation, for example. This is a
2011
temporary and should not be copied. Instead we should fix our code to
2012
always honor name-locks.
2014
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2015
during the call to plugin::StorageEngine::createTable().
2016
See bug #28614 for more info.
2018
static bool create_table_wrapper(Session &session, message::Table& create_table_proto,
2019
TableIdentifier &destination_identifier,
2020
TableIdentifier &src_table,
2021
bool lex_identified_temp_table, bool is_engine_set)
2023
int protoerr= EEXIST;
2024
message::Table new_proto;
2025
message::Table src_proto;
2027
protoerr= plugin::StorageEngine::getTableDefinition(session,
2030
new_proto.CopyFrom(src_proto);
2032
if (lex_identified_temp_table)
2034
new_proto.set_type(message::Table::TEMPORARY);
2038
new_proto.set_type(message::Table::STANDARD);
2043
message::Table::StorageEngine *protoengine;
2045
protoengine= new_proto.mutable_engine();
2046
protoengine->set_name(create_table_proto.engine().name());
2049
if (protoerr && protoerr != EEXIST)
2051
if (errno == ENOENT)
2052
my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName());
2054
my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath(), errno);
2060
As mysql_truncate don't work on a new table at this stage of
2061
creation, instead create the table directly (for both normal
2062
and temporary tables).
2064
int err= plugin::StorageEngine::createTable(session,
2065
destination_identifier,
2068
return err ? false : true;
2203
2072
Create a table identical to the specified table
2243
2109
if (session->open_tables_from_list(&src_table, ¬_used))
2246
strncpy(src_path, src_table->table->s->path.str, sizeof(src_path));
2249
TableIdentifier destination_identifier(db, table_name, lex_identified_temp_table ? TEMP_TABLE : NO_TMP_TABLE);
2112
TableIdentifier destination_identifier(db, table_name,
2113
lex_identified_temp_table ? TEMP_TABLE : STANDARD_TABLE);
2115
TableIdentifier src_identifier(src_table->table->s->db.str,
2116
src_table->table->s->table_name.str, src_table->table->s->tmp_table);
2252
2121
Check that destination tables does not exist. Note that its name
2253
2122
was already checked when it was added to the table list.
2124
bool table_exists= false;
2255
2125
if (lex_identified_temp_table)
2257
2127
if (session->find_temporary_table(db, table_name))
2262
2134
if (session->lock_table_name_if_not_cached(db, table_name, &name_lock))
2267
if (plugin::StorageEngine::getTableDefinition(*session,
2268
destination_identifier) == EEXIST)
2273
Create a new table by copying from source table
2275
Altough exclusive name-lock on target table protects us from concurrent
2276
DML and DDL operations on it we still want to wrap .FRM creation and call
2277
to plugin::StorageEngine::createTable() in critical section protected by
2278
LOCK_open in order to provide minimal atomicity against operations which
2279
disregard name-locks, like I_S implementation, for example. This is a
2280
temporary and should not be copied. Instead we should fix our code to
2281
always honor name-locks.
2283
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
2284
during the call to plugin::StorageEngine::createTable().
2285
See bug #28614 for more info.
2287
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2289
int protoerr= EEXIST;
2292
* If an engine was not specified and we are reading from an I_S table, then we need to toss an
2293
* error. This should go away soon.
2294
* @todo make this go away!
2296
if (! is_engine_set)
2298
string tab_name(src_path);
2299
string i_s_prefix("./information_schema/");
2300
if (tab_name.compare(0, i_s_prefix.length(), i_s_prefix) == 0)
2302
pthread_mutex_unlock(&LOCK_open);
2303
my_error(ER_ILLEGAL_HA_CREATE_OPTION,
2305
"INFORMATION_ENGINE",
2311
protoerr= plugin::StorageEngine::getTableDefinition(*session,
2318
message::Table new_proto(src_proto);
2320
if (lex_identified_temp_table)
2322
new_proto.set_type(message::Table::TEMPORARY);
2326
new_proto.set_type(message::Table::STANDARD);
2331
message::Table::StorageEngine *protoengine;
2333
protoengine= new_proto.mutable_engine();
2334
protoengine->set_name(create_table_proto.engine().name());
2337
if (protoerr == EEXIST)
2339
plugin::StorageEngine* engine= plugin::StorageEngine::findByName(*session,
2340
new_proto.engine().name());
2342
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
2344
string dst_proto_path(destination_identifier.getPath());
2345
dst_proto_path.append(".dfe");
2347
protoerr= drizzle_write_proto_file(dst_proto_path.c_str(), &new_proto);
2357
if (errno == ENOENT)
2358
my_error(ER_BAD_DB_ERROR,MYF(0),db);
2360
my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath(), errno);
2361
pthread_mutex_unlock(&LOCK_open);
2366
As mysql_truncate don't work on a new table at this stage of
2367
creation, instead create the table directly (for both normal
2368
and temporary tables).
2370
err= plugin::StorageEngine::createTable(*session,
2371
destination_identifier,
2374
pthread_mutex_unlock(&LOCK_open);
2376
if (lex_identified_temp_table)
2378
if (err || !session->open_temporary_table(destination_identifier))
2380
(void) session->rm_temporary_table(engine_arg, destination_identifier);
2386
TableIdentifier identifier(db, table_name, NO_TMP_TABLE);
2387
quick_rm_table(*session, identifier);
2393
We have to write the query before we unlock the tables.
2397
Since temporary tables are not replicated under row-based
2398
replication, CREATE TABLE ... LIKE ... needs special
2399
treatement. We have four cases to consider, according to the
2400
following decision table:
2402
==== ========= ========= ==============================
2403
Case Target Source Write to binary log
2404
==== ========= ========= ==============================
2405
1 normal normal Original statement
2406
2 normal temporary Generated statement
2407
3 temporary normal Nothing
2408
4 temporary temporary Nothing
2409
==== ========= ========= ==============================
2411
if (! lex_identified_temp_table)
2413
if (src_table->table->s->tmp_table) // Case 2
2416
String query(buf, sizeof(buf), system_charset_info);
2417
query.length(0); // Have to zero it since constructor doesn't
2421
Here we open the destination table, on which we already have
2422
name-lock. This is needed for store_create_info() to work.
2423
The table will be closed by unlink_open_table() at the end
2426
table->table= name_lock;
2427
pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
2428
if (session->reopen_name_locked_table(table, false))
2430
pthread_mutex_unlock(&LOCK_open);
2433
pthread_mutex_unlock(&LOCK_open);
2435
int result= store_create_info(table, &query, is_if_not_exists);
2437
assert(result == 0); // store_create_info() always return 0
2438
write_bin_log(session, query.ptr(), query.length());
2441
write_bin_log(session, session->query, session->query_length);
2449
if (is_if_not_exists)
2451
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2452
snprintf(warn_buff, sizeof(warn_buff),
2453
ER(ER_TABLE_EXISTS_ERROR), table_name);
2454
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2455
ER_TABLE_EXISTS_ERROR,warn_buff);
2459
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2138
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2139
session->unlink_open_table(name_lock);
2140
pthread_mutex_unlock(&LOCK_open);
2150
else if (plugin::StorageEngine::doesTableExist(*session, destination_identifier))
2158
if (is_if_not_exists)
2160
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2161
snprintf(warn_buff, sizeof(warn_buff),
2162
ER(ER_TABLE_EXISTS_ERROR), table_name);
2163
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2164
ER_TABLE_EXISTS_ERROR,warn_buff);
2169
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2172
else // Otherwise we create the table
2174
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2175
was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2176
src_identifier, lex_identified_temp_table, is_engine_set);
2177
pthread_mutex_unlock(&LOCK_open);
2179
// So we blew the creation of the table, and we scramble to clean up
2180
// anything that might have been created (read... it is a hack)
2181
if (not was_created)
2183
if (lex_identified_temp_table)
2185
(void) session->rm_temporary_table(destination_identifier);
2189
TableIdentifier identifier(db, table_name, STANDARD_TABLE);
2190
quick_rm_table(*session, identifier);
2193
else if (lex_identified_temp_table && not session->open_temporary_table(destination_identifier))
2195
// We created, but we can't open... also, a hack.
2196
(void) session->rm_temporary_table(destination_identifier);
2200
if (not lex_identified_temp_table)
2202
bool rc= replicateCreateTableLike(session, table, name_lock, (src_table->table->s->tmp_table), is_if_not_exists);
2464
2212
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2465
2213
session->unlink_open_table(name_lock);
2466
2214
pthread_mutex_unlock(&LOCK_open);