26
26
#include <drizzled/sql_lex.h>
27
27
#include <drizzled/session.h>
28
28
#include <drizzled/sql_base.h>
29
#include <drizzled/strfunc.h>
29
#include "drizzled/strfunc.h"
30
#include <drizzled/db.h>
30
31
#include <drizzled/lock.h>
31
32
#include <drizzled/unireg.h>
32
33
#include <drizzled/item/int.h>
33
34
#include <drizzled/item/empty_string.h>
34
35
#include <drizzled/transaction_services.h>
35
#include <drizzled/transaction_services.h>
36
#include "drizzled/transaction_services.h"
36
37
#include <drizzled/table_proto.h>
37
38
#include <drizzled/plugin/client.h>
38
39
#include <drizzled/identifier.h>
39
#include <drizzled/internal/m_string.h>
40
#include <drizzled/global_charset_info.h>
41
#include <drizzled/charset.h>
43
#include <drizzled/definition/cache.h>
45
#include <drizzled/statement/alter_table.h>
46
#include <drizzled/sql_table.h>
47
#include <drizzled/pthread_globals.h>
48
#include <drizzled/typelib.h>
49
#include <drizzled/plugin/storage_engine.h>
40
#include "drizzled/internal/m_string.h"
41
#include "drizzled/global_charset_info.h"
42
#include "drizzled/charset.h"
44
#include "drizzled/definition/cache.h"
47
#include "drizzled/statement/alter_table.h"
48
#include "drizzled/sql_table.h"
49
#include "drizzled/pthread_globals.h"
51
51
#include <algorithm>
199
identifier::Table identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
201
message::table::shared_ptr message= plugin::StorageEngine::getTableMessage(*session, identifier, true);
201
TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
203
203
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
205
205
// Table was not found on disk and table can't be created from engine
208
207
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
209
208
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
210
209
table->getTableName());
221
219
/* Generate transaction event ONLY when we successfully drop */
222
220
if (plugin::StorageEngine::dropTable(*session, identifier, local_error))
224
if (message) // If we have no definition, we don't know if the table should have been replicated
226
TransactionServices &transaction_services= TransactionServices::singleton();
227
transaction_services.dropTable(*session, identifier, *message, if_exists);
222
TransactionServices &transaction_services= TransactionServices::singleton();
223
transaction_services.dropTable(session, identifier, if_exists);
1470
1459
/* Build a Table object to pass down to the engine, and the do the actual create. */
1471
1460
if (not prepare_create_table(session, create_info, table_proto, alter_info,
1474
&key_info_buffer, &key_count,
1475
select_field_count))
1463
&key_info_buffer, &key_count,
1464
select_field_count))
1477
1466
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1478
1467
error= locked_create_event(session,
1846
1835
char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1847
1836
uint32_t length;
1848
session->getClient()->store(table_name.c_str());
1837
session->getClient()->store(table_name);
1849
1838
session->getClient()->store(operator_name);
1850
1839
session->getClient()->store(STRING_WITH_LEN("error"));
1851
1840
length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1852
table_name.c_str());
1853
1842
session->getClient()->store(buff, length);
1854
transaction_services.autocommitOrRollback(*session, false);
1843
transaction_services.autocommitOrRollback(session, false);
1855
1844
session->endTransaction(COMMIT);
1856
1845
session->close_thread_tables();
1857
session->getLex()->reset_query_tables_list(false);
1846
lex->reset_query_tables_list(false);
1858
1847
table->table=0; // For query cache
1859
1848
if (session->getClient()->flush())
1868
1857
const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1869
1858
"Waiting to get writelock");
1870
1859
session->abortLock(table->table);
1871
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1860
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1872
1861
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1873
1862
session->exit_cond(old_message);
1874
1863
if (session->getKilled())
1883
session->getLex()->cleanup_after_one_table_open();
1872
lex->cleanup_after_one_table_open();
1884
1873
session->clear_error(); // these errors shouldn't get client
1886
List<DRIZZLE_ERROR>::iterator it(session->warn_list.begin());
1875
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
1887
1876
DRIZZLE_ERROR *err;
1888
1877
while ((err= it++))
1890
session->getClient()->store(table_name.c_str());
1879
session->getClient()->store(table_name);
1891
1880
session->getClient()->store(operator_name);
1892
1881
session->getClient()->store(warning_level_names[err->level].str,
1893
1882
warning_level_names[err->level].length);
1972
1961
boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1973
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1962
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1974
1963
table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1978
transaction_services.autocommitOrRollback(*session, false);
1967
transaction_services.autocommitOrRollback(session, false);
1979
1968
session->endTransaction(COMMIT);
1980
1969
session->close_thread_tables();
1981
1970
table->table=0; // For query cache
2010
1999
during the call to plugin::StorageEngine::createTable().
2011
2000
See bug #28614 for more info.
2013
static bool create_table_wrapper(Session &session,
2014
const message::Table& create_table_proto,
2015
identifier::Table::const_reference destination_identifier,
2016
identifier::Table::const_reference source_identifier,
2002
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
2003
const TableIdentifier &destination_identifier,
2004
const TableIdentifier &src_table,
2017
2005
bool is_engine_set)
2019
// We require an additional table message because during parsing we used
2020
// a "new" message and it will not have all of the information that the
2021
// source table message would have.
2022
message::Table new_table_message;
2024
message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier);
2026
if (not source_table_message)
2028
my_error(ER_TABLE_UNKNOWN, source_identifier);
2032
new_table_message.CopyFrom(*source_table_message);
2007
int protoerr= EEXIST;
2008
message::Table new_proto;
2009
message::table::shared_ptr src_proto;
2011
protoerr= plugin::StorageEngine::getTableDefinition(session,
2014
new_proto.CopyFrom(*src_proto);
2034
2016
if (destination_identifier.isTmp())
2036
new_table_message.set_type(message::Table::TEMPORARY);
2018
new_proto.set_type(message::Table::TEMPORARY);
2040
new_table_message.set_type(message::Table::STANDARD);
2022
new_proto.set_type(message::Table::STANDARD);
2043
2025
if (is_engine_set)
2045
new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
2027
new_proto.mutable_engine()->set_name(create_table_proto.engine().name());
2048
2030
{ // We now do a selective copy of elements on to the new table.
2049
new_table_message.set_name(create_table_proto.name());
2050
new_table_message.set_schema(create_table_proto.schema());
2051
new_table_message.set_catalog(create_table_proto.catalog());
2031
new_proto.set_name(create_table_proto.name());
2032
new_proto.set_schema(create_table_proto.schema());
2033
new_proto.set_catalog(create_table_proto.catalog());
2054
/* Fix names of foreign keys being added */
2055
for (int32_t j= 0; j < new_table_message.fk_constraint_size(); j++)
2036
if (protoerr && protoerr != EEXIST)
2057
if (new_table_message.fk_constraint(j).has_name())
2059
std::string name(new_table_message.name());
2062
name.append("_ibfk_");
2063
snprintf(number, sizeof(number), "%d", j+1);
2064
name.append(number);
2066
message::Table::ForeignKeyConstraint *pfkey= new_table_message.mutable_fk_constraint(j);
2067
pfkey->set_name(name);
2038
if (errno == ENOENT)
2039
my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName().c_str());
2041
my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath().c_str(), errno);
2072
2047
As mysql_truncate don't work on a new table at this stage of
2073
creation, instead create the table directly (for both normal and temporary tables).
2048
creation, instead create the table directly (for both normal
2049
and temporary tables).
2075
bool success= plugin::StorageEngine::createTable(session,
2076
destination_identifier,
2051
int err= plugin::StorageEngine::createTable(session,
2052
destination_identifier,
2079
if (success && not destination_identifier.isTmp())
2055
if (err == false && not destination_identifier.isTmp())
2081
2057
TransactionServices &transaction_services= TransactionServices::singleton();
2082
transaction_services.createTable(session, new_table_message);
2058
transaction_services.createTable(&session, new_proto);
2061
return err ? false : true;
2103
2079
bool create_like_table(Session* session,
2104
identifier::Table::const_reference destination_identifier,
2105
identifier::Table::const_reference source_identifier,
2106
message::Table &create_table_proto,
2107
bool is_if_not_exists,
2080
const TableIdentifier &destination_identifier,
2081
TableList* table, TableList* src_table,
2082
message::Table &create_table_proto,
2083
bool is_if_not_exists,
2110
2086
bool res= true;
2111
bool table_exists= false;
2090
By opening source table we guarantee that it exists and no concurrent
2091
DDL operation will mess with it. Later we also take an exclusive
2092
name-lock on target table name, which makes copying of .frm cursor,
2093
call to plugin::StorageEngine::createTable() and binlogging atomic
2094
against concurrent DML and DDL operations on target table.
2095
Thus by holding both these "locks" we ensure that our statement is
2096
properly isolated from all concurrent operations which matter.
2098
if (session->open_tables_from_list(&src_table, ¬_used))
2101
TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
2102
src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
2114
2107
Check that destination tables does not exist. Note that its name
2202
2193
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2203
2194
snprintf(warn_buff, sizeof(warn_buff),
2204
ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
2195
ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
2205
2196
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2206
ER_TABLE_EXISTS_ERROR, warn_buff);
2210
my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
2197
ER_TABLE_EXISTS_ERROR,warn_buff);
2202
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());