12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
16
/* drop and alter of tables */
36
36
#include "drizzled/transaction_services.h"
37
37
#include <drizzled/table_proto.h>
38
38
#include <drizzled/plugin/client.h>
39
#include <drizzled/table_identifier.h>
39
#include <drizzled/identifier.h>
40
40
#include "drizzled/internal/m_string.h"
41
41
#include "drizzled/global_charset_info.h"
42
42
#include "drizzled/charset.h"
49
49
#include <algorithm>
52
#include <boost/unordered_set.hpp>
52
54
using namespace std;
57
extern plugin::StorageEngine *myisam_engine;
58
59
extern pid_t current_pid;
60
bool is_primary_key(KEY *key_info)
61
bool is_primary_key(KeyInfo *key_info)
62
63
static const char * primary_key_name="PRIMARY";
63
64
return (strcmp(key_info->name, primary_key_name)==0);
75
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
76
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
76
static bool check_if_keyname_exists(const char *name,KeyInfo *start, KeyInfo *end);
77
static char *make_unique_key_name(const char *field_name,KeyInfo *start,KeyInfo *end);
78
79
static bool prepare_blob_field(Session *session, CreateField *sql_field);
111
112
transaction_services.rawStatement(session, query);
115
/* Should should be refactored to go away */
116
void write_bin_log_drop_table(Session *session, bool if_exists, const char *db_name, const char *table_name)
118
TransactionServices &transaction_services= TransactionServices::singleton();
122
built_query.append("DROP TABLE IF EXISTS ");
124
built_query.append("DROP TABLE ");
126
built_query.append("`");
127
if (session->db.empty() || strcmp(db_name, session->db.c_str()) != 0)
129
built_query.append(db_name);
130
built_query.append("`.`");
133
built_query.append(table_name);
134
built_query.append("`");
135
transaction_services.rawStatement(session, built_query);
139
116
Execute the drop of a normal or temporary table
171
148
bool foreign_key_error= false;
173
pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
176
If we have the table in the definition cache, we don't have to check the
177
.frm cursor to find if the table is a normal table (not view) and what
181
for (table= tables; table; table= table->next_local)
183
TableIdentifier identifier(table->db, table->table_name);
185
table->db_type= NULL;
187
if ((share= TableShare::getShare(identifier)))
189
table->db_type= share->db_type();
193
if (not drop_temporary && lock_table_names_exclusively(session, tables))
195
pthread_mutex_unlock(&LOCK_open);
150
LOCK_open.lock(); /* Part 2 of rm a table */
152
if (not drop_temporary && session->lock_table_names_exclusively(tables))
220
179
if (drop_temporary == false)
222
181
Table *locked_table;
223
abort_locked_tables(session, db, table->table_name);
224
remove_table_from_cache(session, db, table->table_name,
225
RTFC_WAIT_OTHER_THREAD_FLAG |
226
RTFC_CHECK_KILLED_FLAG);
182
abort_locked_tables(session, tmp_identifier);
183
table::Cache::singleton().removeTable(session, tmp_identifier,
184
RTFC_WAIT_OTHER_THREAD_FLAG |
185
RTFC_CHECK_KILLED_FLAG);
228
187
If the table was used in lock tables, remember it so that
229
188
unlock_table_names can free it
231
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
190
if ((locked_table= drop_locked_tables(session, tmp_identifier)))
232
191
table->table= locked_table;
193
if (session->getKilled())
237
196
goto err_with_placeholders;
240
TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? message::Table::INTERNAL : message::Table::STANDARD);
199
TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
242
201
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
269
228
if (error == 0 || (if_exists && foreign_key_error == false))
271
230
TransactionServices &transaction_services= TransactionServices::singleton();
272
transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
231
transaction_services.dropTable(session, string(table->getSchemaName()), string(table->getTableName()), if_exists);
277
236
if (wrong_tables.length())
278
237
wrong_tables.append(',');
279
wrong_tables.append(String(table->table_name,system_charset_info));
238
wrong_tables.append(String(table->getTableName(), system_charset_info));
283
242
It's safe to unlock LOCK_open: we have an exclusive lock
284
243
on the table name.
286
pthread_mutex_unlock(&LOCK_open);
289
248
if (wrong_tables.length())
303
pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
262
LOCK_open.lock(); /* final bit in rm table lock */
305
264
err_with_placeholders:
306
unlock_table_names(tables, NULL);
307
pthread_mutex_unlock(&LOCK_open);
265
tables->unlock_table_names();
308
267
session->no_warnings_for_error= 0;
358
class typelib_set_member
362
const CHARSET_INFO * const cs;
364
typelib_set_member(const char* value, unsigned int length,
365
const CHARSET_INFO * const charset)
371
static bool operator==(typelib_set_member const& a, typelib_set_member const& b)
373
return (my_strnncoll(a.cs,
374
(const unsigned char*)a.s.c_str(), a.s.length(),
375
(const unsigned char*)b.s.c_str(), b.s.length())==0);
381
class typelib_set_member_hasher
383
boost::hash<string> hasher;
385
std::size_t operator()(const typelib_set_member& t) const
399
392
static bool check_duplicates_in_interval(const char *set_or_name,
400
393
const char *name, TYPELIB *typelib,
401
394
const CHARSET_INFO * const cs,
406
399
unsigned int *cur_length= typelib->type_lengths;
407
400
*dup_val_count= 0;
409
for ( ; tmp.count > 1; cur_value++, cur_length++)
402
boost::unordered_set<typelib_set_member, typelib_set_member_hasher> interval_set;
404
for ( ; tmp.count > 0; cur_value++, cur_length++)
411
406
tmp.type_names++;
412
407
tmp.type_lengths++;
414
if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
409
if (interval_set.find(typelib_set_member(*cur_value, *cur_length, cs)) != interval_set.end())
416
411
my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
417
412
name,*cur_value,set_or_name);
416
interval_set.insert(typelib_set_member(*cur_value, *cur_length, cs));
490
487
switch (sql_field->sql_type) {
491
488
case DRIZZLE_TYPE_BLOB:
492
sql_field->pack_flag= pack_length_to_packflag(sql_field->pack_length - portable_sizeof_char_ptr);
493
489
sql_field->length= 8; // Unireg field length
494
490
(*blob_columns)++;
496
492
case DRIZZLE_TYPE_VARCHAR:
497
sql_field->pack_flag=0;
499
494
case DRIZZLE_TYPE_ENUM:
500
sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length);
501
495
if (check_duplicates_in_interval("ENUM",
502
496
sql_field->field_name,
503
497
sql_field->interval,
508
502
case DRIZZLE_TYPE_DATE: // Rest of string types
509
503
case DRIZZLE_TYPE_DATETIME:
510
504
case DRIZZLE_TYPE_NULL:
511
sql_field->pack_flag=f_settype((uint32_t) sql_field->sql_type);
513
506
case DRIZZLE_TYPE_DECIMAL:
514
sql_field->pack_flag= 0;
516
508
case DRIZZLE_TYPE_TIMESTAMP:
517
509
/* We should replace old TIMESTAMP fields with their newer analogs */
552
545
CreateField *sql_field,*dup_field;
553
546
uint field,null_fields,blob_columns,max_key_length;
554
547
ulong record_offset= 0;
556
KEY_PART_INFO *key_part_info;
549
KeyPartInfo *key_part_info;
557
550
int timestamps= 0, timestamps_with_niladic= 0;
558
551
int field_no,dup_no;
559
552
int select_field_pos,auto_increment=0;
664
657
if (String::needs_conversion(tmp->length(), tmp->charset(),
668
661
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
669
interval->type_names[i]= strmake_root(session->mem_root, conv.ptr(),
662
interval->type_names[i]= session->mem_root->strmake_root(conv.ptr(), conv.length());
671
663
interval->type_lengths[i]= conv.length();
710
calculate_interval_lengths(cs, interval, &field_length, &dummy);
703
calculate_interval_lengths(cs, interval, &field_length, &new_dummy);
711
704
sql_field->length= field_length;
713
706
set_if_smaller(sql_field->length, (uint32_t)MAX_FIELD_WIDTH-1);
775
768
/** @todo Get rid of this MyISAM-specific crap. */
776
769
if (not create_proto.engine().name().compare("MyISAM") &&
777
770
((sql_field->flags & BLOB_FLAG) ||
778
(sql_field->sql_type == DRIZZLE_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED)))
771
(sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)))
779
772
(*db_options)|= HA_OPTION_PACK_RECORD;
878
882
key2->name.str != ignore_key &&
879
883
!foreign_key_prefix(key, key2)))
881
/* TODO: issue warning message */
885
/* @todo issue warning message */
882
886
/* mark that the generated key should be ignored */
883
887
if (!key2->generated ||
884
888
(key->generated && key->columns.elements <
915
(*key_info_buffer)= key_info= (KEY*) memory::sql_calloc(sizeof(KEY) * (*key_count));
916
key_part_info=(KEY_PART_INFO*) memory::sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
919
(*key_info_buffer)= key_info= (KeyInfo*) memory::sql_calloc(sizeof(KeyInfo) * (*key_count));
920
key_part_info=(KeyPartInfo*) memory::sql_calloc(sizeof(KeyPartInfo)*key_parts);
917
921
if (!*key_info_buffer || ! key_part_info)
918
922
return(true); // Out of memory
953
957
key_info->usable_key_parts= key_number;
954
958
key_info->algorithm= key->key_create_info.algorithm;
956
/* Take block size from key part or table part */
958
TODO: Add warning if block size changes. We can't do it here, as
959
this may depend on the size of the key
961
key_info->block_size= (key->key_create_info.block_size ?
962
key->key_create_info.block_size :
963
create_proto.options().key_block_size());
965
if (key_info->block_size)
966
key_info->flags|= HA_USES_BLOCK_SIZE;
968
960
uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
969
961
key->key_create_info.comment.str,
970
962
key->key_create_info.comment.str +
1142
1134
key_part_info->length=(uint16_t) length;
1143
1135
/* Use packed keys for long strings on the first column */
1144
1136
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
1145
(length >= KEY_DEFAULT_PACK_LENGTH &&
1146
(sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
1147
sql_field->sql_type == DRIZZLE_TYPE_BLOB)))
1137
(length >= KEY_DEFAULT_PACK_LENGTH &&
1138
(sql_field->sql_type == DRIZZLE_TYPE_VARCHAR ||
1139
sql_field->sql_type == DRIZZLE_TYPE_BLOB)))
1149
1141
if ((column_nr == 0 && sql_field->sql_type == DRIZZLE_TYPE_BLOB) ||
1150
1142
sql_field->sql_type == DRIZZLE_TYPE_VARCHAR)
1151
1144
key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
1153
1148
key_info->flags|= HA_PACK_KEY;
1155
1151
/* Check if the key segment is partial, set the key flag accordingly */
1156
1152
if (length != sql_field->key_length)
1440
1435
assert(identifier.getTableName() == table_proto.name());
1441
1436
db_options= create_info->table_options;
1443
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1444
db_options|=HA_OPTION_PACK_RECORD;
1446
1438
set_table_default_charset(create_info, identifier.getSchemaName().c_str());
1448
1440
/* Build a Table object to pass down to the engine, and the do the actual create. */
1449
1441
if (not mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1452
&key_info_buffer, &key_count,
1453
select_field_count))
1444
&key_info_buffer, &key_count,
1445
select_field_count))
1455
pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1447
boost_unique_lock_t lock(LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1456
1448
error= locked_create_event(session,
1571
check_if_keyname_exists(const char *name, KEY *start, KEY *end)
1561
check_if_keyname_exists(const char *name, KeyInfo *start, KeyInfo *end)
1573
for (KEY *key=start ; key != end ; key++)
1563
for (KeyInfo *key=start ; key != end ; key++)
1574
1564
if (!my_strcasecmp(system_charset_info,name,key->name))
1615
1605
mysql_rename_table()
1616
1607
base The plugin::StorageEngine handle.
1617
1608
old_db The old database name.
1618
1609
old_name The old table name.
1619
1610
new_db The new database name.
1620
1611
new_name The new table name.
1621
flags flags for build_table_filename().
1622
FN_FROM_IS_TMP old_name is temporary.
1623
FN_TO_IS_TMP new_name is temporary.
1685
1672
enum ha_extra_function function)
1688
safe_mutex_assert_owner(&LOCK_open);
1675
safe_mutex_assert_owner(LOCK_open.native_handle());
1690
1677
table->cursor->extra(function);
1691
1678
/* Mark all tables that are in use as 'old' */
1692
mysql_lock_abort(session, table); /* end threads waiting on lock */
1679
session->abortLock(table); /* end threads waiting on lock */
1694
1681
/* Wait until all there are no other threads that has this table open */
1695
remove_table_from_cache(session, table->s->getSchemaName(),
1696
table->s->table_name.str,
1697
RTFC_WAIT_OTHER_THREAD_FLAG);
1682
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1683
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1721
1707
/* Close lock if this is not got with LOCK TABLES */
1724
mysql_unlock_tables(this, lock);
1725
1711
lock= NULL; // Start locked threads
1727
1713
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
1728
1714
unlink_open_table(table);
1730
1716
/* When lock on LOCK_open is freed other threads can continue */
1731
broadcast_refresh();
1717
locking::broadcast_refresh();
1772
1758
for (table= tables; table; table= table->next_local)
1774
1760
char table_name[NAME_LEN*2+2];
1775
char* db = table->db;
1776
1761
bool fatal_error=0;
1778
sprintf(table_name,"%s.%s",db,table->table_name);
1763
snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
1779
1764
table->lock_type= lock_type;
1780
1765
/* open only one table from local list of command */
1789
1774
Time zone tables and SP tables can be add to lex->query_tables list,
1790
1775
so it have to be prepared.
1791
TODO: Investigate if we can put extra tables into argument instead of
1792
using lex->query_tables
1776
@todo Investigate if we can put extra tables into argument instead of using lex->query_tables
1794
1778
lex->query_tables= table;
1795
1779
lex->query_tables_last= &table->next_global;
1829
1813
length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1831
1815
session->client->store(buff, length);
1832
transaction_services.ha_autocommit_or_rollback(session, false);
1816
transaction_services.autocommitOrRollback(session, false);
1833
1817
session->endTransaction(COMMIT);
1834
1818
session->close_thread_tables();
1835
1819
lex->reset_query_tables_list(false);
1842
1826
/* Close all instances of the table to allow repair to rename files */
1843
if (lock_type == TL_WRITE && table->table->s->version)
1827
if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1845
pthread_mutex_lock(&LOCK_open); /* Lock type is TL_WRITE and we lock to repair the table */
1846
const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
1847
"Waiting to get writelock");
1848
mysql_lock_abort(session,table->table);
1849
remove_table_from_cache(session, table->table->s->getSchemaName(),
1850
table->table->s->table_name.str,
1851
RTFC_WAIT_OTHER_THREAD_FLAG |
1852
RTFC_CHECK_KILLED_FLAG);
1829
LOCK_open.lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1830
const char *old_message=session->enter_cond(COND_refresh, LOCK_open,
1831
"Waiting to get writelock");
1832
session->abortLock(table->table);
1833
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1834
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1853
1835
session->exit_cond(old_message);
1854
if (session->killed)
1836
if (session->getKilled())
1856
1838
open_for_modify= 0;
1938
1920
if (table->table)
1940
1922
if (fatal_error)
1941
table->table->s->version=0; // Force close of table
1924
table->table->getMutableShare()->resetVersion(); // Force close of table
1942
1926
else if (open_for_modify)
1944
if (table->table->s->tmp_table)
1928
if (table->table->getShare()->getType())
1945
1930
table->table->cursor->info(HA_STATUS_CONST);
1948
pthread_mutex_lock(&LOCK_open);
1949
remove_table_from_cache(session, table->table->s->getSchemaName(),
1950
table->table->s->table_name.str, RTFC_NO_FLAG);
1951
pthread_mutex_unlock(&LOCK_open);
1934
boost::unique_lock<boost::mutex> lock(LOCK_open);
1935
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1936
table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1955
transaction_services.ha_autocommit_or_rollback(session, false);
1940
transaction_services.autocommitOrRollback(session, false);
1956
1941
session->endTransaction(COMMIT);
1957
1942
session->close_thread_tables();
1958
1943
table->table=0; // For query cache
1976
We have to write the query before we unlock the named table.
1978
Since temporary tables are not replicated under row-based
1979
replication, CREATE TABLE ... LIKE ... needs special
1980
treatement. We have four cases to consider, according to the
1981
following decision table:
1983
==== ========= ========= ==============================
1984
Case Target Source Write to binary log
1985
==== ========= ========= ==============================
1986
1 normal normal Original statement
1987
2 normal temporary Generated statement
1988
3 temporary normal Nothing
1989
4 temporary temporary Nothing
1990
==== ========= ========= ==============================
1992
static bool replicateCreateTableLike(Session *session, TableList *table, Table *name_lock,
1993
bool is_src_table_tmp, bool is_if_not_exists)
1995
if (is_src_table_tmp)
1998
String query(buf, sizeof(buf), system_charset_info);
1999
query.length(0); // Have to zero it since constructor doesn't
2003
Here we open the destination table, on which we already have
2004
name-lock. This is needed for store_create_info() to work.
2005
The table will be closed by unlink_open_table() at the end
2008
table->table= name_lock;
2009
pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
2010
if (session->reopen_name_locked_table(table, false))
2012
pthread_mutex_unlock(&LOCK_open);
2015
pthread_mutex_unlock(&LOCK_open);
2017
int result= store_create_info(table, &query, is_if_not_exists);
2019
assert(result == 0); // store_create_info() always return 0
2020
write_bin_log(session, query.ptr());
2024
write_bin_log(session, session->query.c_str());
2031
1961
Create a new table by copying from source table
2097
2024
int err= plugin::StorageEngine::createTable(session,
2098
2025
destination_identifier,
2028
if (err == false && not destination_identifier.isTmp())
2030
TransactionServices &transaction_services= TransactionServices::singleton();
2031
transaction_services.createTable(&session, new_proto);
2101
2034
return err ? false : true;
2142
2071
if (session->open_tables_from_list(&src_table, ¬_used))
2145
TableIdentifier src_identifier(src_table->table->s->getSchemaName(),
2146
src_table->table->s->table_name.str, src_table->table->s->tmp_table);
2074
TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
2075
src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
2151
2080
Check that destination tables does not exist. Note that its name
2152
2081
was already checked when it was added to the table list.
2083
For temporary tables we don't aim to grab locks.
2154
2085
bool table_exists= false;
2155
2086
if (destination_identifier.isTmp())
2157
if (session->find_temporary_table(db, table_name))
2088
if (session->find_temporary_table(destination_identifier))
2159
2090
table_exists= true;
2094
bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2095
src_identifier, is_engine_set);
2096
if (not was_created) // This is pretty paranoid, but we assume something might not clean up after itself
2098
(void) session->rm_temporary_table(destination_identifier, true);
2100
else if (not session->open_temporary_table(destination_identifier))
2102
// We created, but we can't open... also, a hack.
2103
(void) session->rm_temporary_table(destination_identifier, true);
2111
else // Standard table which will require locks.
2164
if (session->lock_table_name_if_not_cached(db, table_name, &name_lock))
2113
Table *name_lock= 0;
2115
if (session->lock_table_name_if_not_cached(destination_identifier, &name_lock))
2168
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2119
boost_unique_lock_t lock(LOCK_open); /* unlink open tables for create table like*/
2169
2120
session->unlink_open_table(name_lock);
2170
pthread_mutex_unlock(&LOCK_open);
2182
2132
table_exists= true;
2134
else // Otherwise we create the table
2138
boost_unique_lock_t lock(LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2139
was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2140
src_identifier, is_engine_set);
2143
// So we blew the creation of the table, and we scramble to clean up
2144
// anything that might have been created (read... it is a hack)
2145
if (not was_created)
2147
quick_rm_table(*session, destination_identifier);
2157
boost_unique_lock_t lock(LOCK_open); /* unlink open tables for create table like*/
2158
session->unlink_open_table(name_lock);
2186
2162
if (table_exists)
2190
2166
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2191
2167
snprintf(warn_buff, sizeof(warn_buff),
2192
ER(ER_TABLE_EXISTS_ERROR), table_name);
2168
ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
2193
2169
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2194
2170
ER_TABLE_EXISTS_ERROR,warn_buff);
2199
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
2202
else // Otherwise we create the table
2204
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2205
was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2206
src_identifier, is_engine_set);
2207
pthread_mutex_unlock(&LOCK_open);
2209
// So we blew the creation of the table, and we scramble to clean up
2210
// anything that might have been created (read... it is a hack)
2211
if (not was_created)
2213
if (destination_identifier.isTmp())
2215
(void) session->rm_temporary_table(destination_identifier);
2219
quick_rm_table(*session, destination_identifier);
2222
else if (destination_identifier.isTmp() && not session->open_temporary_table(destination_identifier))
2224
// We created, but we can't open... also, a hack.
2225
(void) session->rm_temporary_table(destination_identifier);
2229
if (not destination_identifier.isTmp())
2231
bool rc= replicateCreateTableLike(session, table, name_lock, (src_table->table->s->tmp_table), is_if_not_exists);
2241
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2242
session->unlink_open_table(name_lock);
2243
pthread_mutex_unlock(&LOCK_open);
2175
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
2267
2200
&Cursor::ha_check));
2271
bool mysql_checksum_table(Session *session, TableList *tables,
2275
List<Item> field_list;
2278
field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
2279
item->maybe_null= 1;
2280
field_list.push_back(item= new Item_int("Checksum", (int64_t) 1,
2281
MY_INT64_NUM_DECIMAL_DIGITS));
2282
item->maybe_null= 1;
2283
if (session->client->sendFields(&field_list))
2286
/* Open one table after the other to keep lock time as short as possible. */
2287
for (table= tables; table; table= table->next_local)
2289
char table_name[NAME_LEN*2+2];
2292
sprintf(table_name,"%s.%s",table->db,table->table_name);
2294
t= table->table= session->openTableLock(table, TL_READ);
2295
session->clear_error(); // these errors shouldn't get client
2297
session->client->store(table_name);
2301
/* Table didn't exist */
2302
session->client->store();
2303
session->clear_error();
2308
@note if the engine keeps a checksum then we return the checksum, otherwise we calculate
2310
if (t->cursor->getEngine()->check_flag(HTON_BIT_HAS_CHECKSUM))
2312
session->client->store((uint64_t)t->cursor->checksum());
2316
/* calculating table's checksum */
2317
internal::ha_checksum crc= 0;
2318
unsigned char null_mask=256 - (1 << t->s->last_null_bit_pos);
2320
t->use_all_columns();
2322
if (t->cursor->ha_rnd_init(1))
2323
session->client->store();
2328
internal::ha_checksum row_crc= 0;
2329
int error= t->cursor->rnd_next(t->record[0]);
2330
if (unlikely(error))
2332
if (error == HA_ERR_RECORD_DELETED)
2336
if (t->s->null_bytes)
2338
/* fix undefined null bits */
2339
t->record[0][t->s->null_bytes-1] |= null_mask;
2340
if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
2341
t->record[0][0] |= 1;
2343
row_crc= internal::my_checksum(row_crc, t->record[0], t->s->null_bytes);
2346
for (uint32_t i= 0; i < t->s->fields; i++ )
2348
Field *f= t->field[i];
2349
if ((f->type() == DRIZZLE_TYPE_BLOB) ||
2350
(f->type() == DRIZZLE_TYPE_VARCHAR))
2354
row_crc= internal::my_checksum(row_crc, (unsigned char*) tmp.ptr(), tmp.length());
2357
row_crc= internal::my_checksum(row_crc, f->ptr,
2363
session->client->store((uint64_t)crc);
2364
t->cursor->ha_rnd_end();
2367
session->clear_error();
2368
session->close_thread_tables();
2369
table->table=0; // For query cache
2371
if (session->client->flush())
2379
session->close_thread_tables(); // Shouldn't be needed
2385
2203
} /* namespace drizzled */