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>
193
195
if (session->getKilled())
198
goto err_with_placeholders;
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());
219
drizzled::error_t local_error;
221
/* Generate transaction event ONLY when we successfully drop */
222
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);
232
if (local_error == HA_ERR_NO_SUCH_TABLE and if_exists)
235
session->clear_error();
238
if (local_error == HA_ERR_ROW_IS_REFERENCED)
240
/* the table is referenced by a foreign key constraint */
241
foreign_key_error= true;
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);
249
wrong_tables.push_back(table->getTableName());
238
if (wrong_tables.length())
239
wrong_tables.append(',');
240
wrong_tables.append(String(table->getTableName(), system_charset_info));
253
tables->unlock_table_names();
257
if (wrong_tables.size())
244
It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
247
table::Cache::singleton().mutex().unlock();
251
if (wrong_tables.length())
259
253
if (not foreign_key_error)
261
std::string table_error;
263
for (util::string::vector::iterator iter= wrong_tables.begin();
264
iter != wrong_tables.end();
270
table_error.resize(table_error.size() -1);
272
255
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
273
table_error.c_str());
256
wrong_tables.c_ptr());
483
471
sql_field->length= 8; // Unireg field length
484
472
(*blob_columns)++;
474
case DRIZZLE_TYPE_VARCHAR:
487
476
case DRIZZLE_TYPE_ENUM:
489
if (check_duplicates_in_interval("ENUM",
490
sql_field->field_name,
500
case DRIZZLE_TYPE_MICROTIME:
477
if (check_duplicates_in_interval("ENUM",
478
sql_field->field_name,
484
case DRIZZLE_TYPE_DATE: // Rest of string types
485
case DRIZZLE_TYPE_DATETIME:
486
case DRIZZLE_TYPE_NULL:
488
case DRIZZLE_TYPE_DECIMAL:
501
490
case DRIZZLE_TYPE_TIMESTAMP:
502
491
/* We should replace old TIMESTAMP fields with their newer analogs */
503
492
if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
515
504
else if (sql_field->unireg_check != Field::NONE)
517
505
(*timestamps_with_niladic)++;
524
case DRIZZLE_TYPE_BOOLEAN:
525
case DRIZZLE_TYPE_DATE: // Rest of string types
526
case DRIZZLE_TYPE_DATETIME:
527
case DRIZZLE_TYPE_DECIMAL:
528
case DRIZZLE_TYPE_DOUBLE:
529
case DRIZZLE_TYPE_LONG:
530
case DRIZZLE_TYPE_LONGLONG:
531
case DRIZZLE_TYPE_NULL:
532
case DRIZZLE_TYPE_TIME:
533
case DRIZZLE_TYPE_UUID:
534
case DRIZZLE_TYPE_VARCHAR:
541
static int prepare_create_table(Session *session,
542
HA_CREATE_INFO *create_info,
543
message::Table &create_proto,
544
AlterInfo *alter_info,
546
uint32_t *db_options,
547
KeyInfo **key_info_buffer,
549
int select_field_count)
516
static int mysql_prepare_create_table(Session *session,
517
HA_CREATE_INFO *create_info,
518
message::Table &create_proto,
519
AlterInfo *alter_info,
521
uint32_t *db_options,
522
KeyInfo **key_info_buffer,
524
int select_field_count)
551
526
const char *key_name;
552
527
CreateField *sql_field,*dup_field;
993
963
message::Table::Field *protofield= NULL;
995
List<Key_part_spec>::iterator cols(key->columns.begin());
996
List<Key_part_spec>::iterator cols2(key->columns.begin());
965
List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
997
966
for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
1000
969
Key_part_spec *dup_column;
1001
970
int proto_field_nr= 0;
1003
it= alter_info->create_list.begin();
1005
974
while ((sql_field=it++) && ++proto_field_nr &&
1006
975
my_strcasecmp(system_charset_info,
1007
976
column->field_name.str,
1008
977
sql_field->field_name))
1015
981
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
1019
984
while ((dup_column= cols2++) != column)
1021
986
if (!my_strcasecmp(system_charset_info,
1200
1163
key_info->name=(char*) key_name;
1204
1166
if (!key_info->name || check_column_name(key_info->name))
1206
1168
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1210
1171
if (!(key_info->flags & HA_NULL_PART_KEY))
1215
1173
key_info->key_length=(uint16_t) key_length;
1217
1174
if (key_length > max_key_length)
1219
1176
my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1226
1181
if (!unique_key && !primary_key &&
1227
1182
(engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1229
1184
my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1233
1187
if (auto_increment > 0)
1235
1189
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1468
1426
set_table_default_charset(create_info, identifier.getSchemaName().c_str());
1470
1428
/* Build a Table object to pass down to the engine, and the do the actual create. */
1471
if (not prepare_create_table(session, create_info, table_proto, alter_info,
1474
&key_info_buffer, &key_count,
1475
select_field_count))
1429
if (not mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1432
&key_info_buffer, &key_count,
1433
select_field_count))
1477
1435
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1478
1436
error= locked_create_event(session,
1552
Database locking aware wrapper for create_table_no_lock(),
1512
Database locking aware wrapper for mysql_create_table_no_lock(),
1554
bool create_table(Session *session,
1555
const identifier::Table &identifier,
1514
bool mysql_create_table(Session *session,
1515
const TableIdentifier &identifier,
1556
1516
HA_CREATE_INFO *create_info,
1557
1517
message::Table &table_proto,
1558
1518
AlterInfo *alter_info,
1788
1748
item->maybe_null = 1;
1789
1749
field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
1790
1750
item->maybe_null = 1;
1791
if (session->getClient()->sendFields(&field_list))
1751
if (session->client->sendFields(&field_list))
1794
1754
for (table= tables; table; table= table->next_local)
1796
identifier::Table table_identifier(table->getSchemaName(), table->getTableName());
1797
std::string table_name;
1756
char table_name[NAME_LEN*2+2];
1798
1757
bool fatal_error=0;
1800
table_identifier.getSQLPath(table_name);
1759
snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
1802
1760
table->lock_type= lock_type;
1803
1761
/* open only one table from local list of command */
1846
1804
char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1847
1805
uint32_t length;
1848
session->getClient()->store(table_name.c_str());
1849
session->getClient()->store(operator_name);
1850
session->getClient()->store(STRING_WITH_LEN("error"));
1806
session->client->store(table_name);
1807
session->client->store(operator_name);
1808
session->client->store(STRING_WITH_LEN("error"));
1851
1809
length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1852
table_name.c_str());
1853
session->getClient()->store(buff, length);
1854
transaction_services.autocommitOrRollback(*session, false);
1811
session->client->store(buff, length);
1812
transaction_services.autocommitOrRollback(session, false);
1855
1813
session->endTransaction(COMMIT);
1856
1814
session->close_thread_tables();
1857
session->getLex()->reset_query_tables_list(false);
1815
lex->reset_query_tables_list(false);
1858
1816
table->table=0; // For query cache
1859
if (session->getClient()->flush())
1817
if (session->client->flush())
1868
1826
const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1869
1827
"Waiting to get writelock");
1870
1828
session->abortLock(table->table);
1871
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1829
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1872
1830
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1873
1831
session->exit_cond(old_message);
1874
1832
if (session->getKilled())
1883
session->getLex()->cleanup_after_one_table_open();
1841
lex->cleanup_after_one_table_open();
1884
1842
session->clear_error(); // these errors shouldn't get client
1886
List<DRIZZLE_ERROR>::iterator it(session->warn_list.begin());
1844
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
1887
1845
DRIZZLE_ERROR *err;
1888
1846
while ((err= it++))
1890
session->getClient()->store(table_name.c_str());
1891
session->getClient()->store(operator_name);
1892
session->getClient()->store(warning_level_names[err->level].str,
1848
session->client->store(table_name);
1849
session->client->store(operator_name);
1850
session->client->store(warning_level_names[err->level].str,
1893
1851
warning_level_names[err->level].length);
1894
session->getClient()->store(err->msg);
1895
if (session->getClient()->flush())
1852
session->client->store(err->msg);
1853
if (session->client->flush())
1898
1856
drizzle_reset_errors(session, true);
1900
session->getClient()->store(table_name.c_str());
1901
session->getClient()->store(operator_name);
1858
session->client->store(table_name);
1859
session->client->store(operator_name);
1903
1861
switch (result_code) {
1904
1862
case HA_ADMIN_NOT_IMPLEMENTED:
1906
1864
char buf[ERRMSGSIZE+20];
1907
1865
uint32_t length=snprintf(buf, ERRMSGSIZE,
1908
1866
ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
1909
session->getClient()->store(STRING_WITH_LEN("note"));
1910
session->getClient()->store(buf, length);
1867
session->client->store(STRING_WITH_LEN("note"));
1868
session->client->store(buf, length);
1914
1872
case HA_ADMIN_OK:
1915
session->getClient()->store(STRING_WITH_LEN("status"));
1916
session->getClient()->store(STRING_WITH_LEN("OK"));
1873
session->client->store(STRING_WITH_LEN("status"));
1874
session->client->store(STRING_WITH_LEN("OK"));
1919
1877
case HA_ADMIN_FAILED:
1920
session->getClient()->store(STRING_WITH_LEN("status"));
1921
session->getClient()->store(STRING_WITH_LEN("Operation failed"));
1878
session->client->store(STRING_WITH_LEN("status"));
1879
session->client->store(STRING_WITH_LEN("Operation failed"));
1924
1882
case HA_ADMIN_REJECT:
1925
session->getClient()->store(STRING_WITH_LEN("status"));
1926
session->getClient()->store(STRING_WITH_LEN("Operation need committed state"));
1883
session->client->store(STRING_WITH_LEN("status"));
1884
session->client->store(STRING_WITH_LEN("Operation need committed state"));
1927
1885
open_for_modify= false;
1930
1888
case HA_ADMIN_ALREADY_DONE:
1931
session->getClient()->store(STRING_WITH_LEN("status"));
1932
session->getClient()->store(STRING_WITH_LEN("Table is already up to date"));
1889
session->client->store(STRING_WITH_LEN("status"));
1890
session->client->store(STRING_WITH_LEN("Table is already up to date"));
1935
1893
case HA_ADMIN_CORRUPT:
1936
session->getClient()->store(STRING_WITH_LEN("error"));
1937
session->getClient()->store(STRING_WITH_LEN("Corrupt"));
1894
session->client->store(STRING_WITH_LEN("error"));
1895
session->client->store(STRING_WITH_LEN("Corrupt"));
1941
1899
case HA_ADMIN_INVALID:
1942
session->getClient()->store(STRING_WITH_LEN("error"));
1943
session->getClient()->store(STRING_WITH_LEN("Invalid argument"));
1900
session->client->store(STRING_WITH_LEN("error"));
1901
session->client->store(STRING_WITH_LEN("Invalid argument"));
1946
1904
default: // Probably HA_ADMIN_INTERNAL_ERROR
1972
1930
boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1973
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1931
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1974
1932
table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1978
transaction_services.autocommitOrRollback(*session, false);
1936
transaction_services.autocommitOrRollback(session, false);
1979
1937
session->endTransaction(COMMIT);
1980
1938
session->close_thread_tables();
1981
1939
table->table=0; // For query cache
1982
if (session->getClient()->flush())
1940
if (session->client->flush())
2010
1968
during the call to plugin::StorageEngine::createTable().
2011
1969
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,
1971
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
const TableIdentifier &destination_identifier,
1973
const TableIdentifier &src_table,
2017
1974
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);
1976
int protoerr= EEXIST;
1977
message::Table new_proto;
1978
message::table::shared_ptr src_proto;
1980
protoerr= plugin::StorageEngine::getTableDefinition(session,
1983
new_proto.CopyFrom(*src_proto);
2034
1985
if (destination_identifier.isTmp())
2036
new_table_message.set_type(message::Table::TEMPORARY);
1987
new_proto.set_type(message::Table::TEMPORARY);
2040
new_table_message.set_type(message::Table::STANDARD);
1991
new_proto.set_type(message::Table::STANDARD);
2043
1994
if (is_engine_set)
2045
new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
1996
new_proto.mutable_engine()->set_name(create_table_proto.engine().name());
2048
1999
{ // 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());
2000
new_proto.set_name(create_table_proto.name());
2001
new_proto.set_schema(create_table_proto.schema());
2002
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++)
2005
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);
2007
if (errno == ENOENT)
2008
my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName().c_str());
2010
my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath().c_str(), errno);
2072
2016
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).
2017
creation, instead create the table directly (for both normal
2018
and temporary tables).
2075
bool success= plugin::StorageEngine::createTable(session,
2076
destination_identifier,
2020
int err= plugin::StorageEngine::createTable(session,
2021
destination_identifier,
2079
if (success && not destination_identifier.isTmp())
2024
if (err == false && not destination_identifier.isTmp())
2081
2026
TransactionServices &transaction_services= TransactionServices::singleton();
2082
transaction_services.createTable(session, new_table_message);
2027
transaction_services.createTable(&session, new_proto);
2030
return err ? false : true;
2089
2034
Create a table identical to the specified table
2037
mysql_create_like_table()
2093
2038
session Thread object
2094
2039
table Table list element for target table
2095
2040
src_table Table list element for source table
2103
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,
2048
bool mysql_create_like_table(Session* session,
2049
const TableIdentifier &destination_identifier,
2050
TableList* table, TableList* src_table,
2051
message::Table &create_table_proto,
2052
bool is_if_not_exists,
2110
2055
bool res= true;
2111
bool table_exists= false;
2059
By opening source table we guarantee that it exists and no concurrent
2060
DDL operation will mess with it. Later we also take an exclusive
2061
name-lock on target table name, which makes copying of .frm cursor,
2062
call to plugin::StorageEngine::createTable() and binlogging atomic
2063
against concurrent DML and DDL operations on target table.
2064
Thus by holding both these "locks" we ensure that our statement is
2065
properly isolated from all concurrent operations which matter.
2067
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());
2114
2076
Check that destination tables does not exist. Note that its name
2202
2162
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2203
2163
snprintf(warn_buff, sizeof(warn_buff),
2204
ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
2164
ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
2205
2165
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2206
ER_TABLE_EXISTS_ERROR, warn_buff);
2210
my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
2166
ER_TABLE_EXISTS_ERROR,warn_buff);
2171
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
2219
bool analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2179
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2221
2181
thr_lock_type lock_type = TL_READ_NO_INSERT;
2223
return(admin_table(session, tables, check_opt,
2183
return(mysql_admin_table(session, tables, check_opt,
2224
2184
"analyze", lock_type, true,
2225
2185
&Cursor::ha_analyze));
2229
bool check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
2189
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
2231
2191
thr_lock_type lock_type = TL_READ_NO_INSERT;
2233
return(admin_table(session, tables, check_opt,
2193
return(mysql_admin_table(session, tables, check_opt,
2234
2194
"check", lock_type,
2236
2196
&Cursor::ha_check));