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"
30
#include <drizzled/db.h>
29
#include <drizzled/strfunc.h>
31
30
#include <drizzled/lock.h>
32
31
#include <drizzled/unireg.h>
33
32
#include <drizzled/item/int.h>
34
33
#include <drizzled/item/empty_string.h>
35
34
#include <drizzled/transaction_services.h>
36
#include "drizzled/transaction_services.h"
35
#include <drizzled/transaction_services.h>
37
36
#include <drizzled/table_proto.h>
38
37
#include <drizzled/plugin/client.h>
39
38
#include <drizzled/identifier.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"
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>
51
51
#include <algorithm>
195
193
if (session->getKilled())
198
goto err_with_placeholders;
201
TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
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);
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
207
208
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
208
209
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
209
210
table->getTableName());
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);
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;
238
if (wrong_tables.length())
239
wrong_tables.append(',');
240
wrong_tables.append(String(table->getTableName(), system_charset_info));
249
wrong_tables.push_back(table->getTableName());
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())
253
tables->unlock_table_names();
257
if (wrong_tables.size())
253
259
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);
255
272
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
256
wrong_tables.c_ptr());
273
table_error.c_str());
471
483
sql_field->length= 8; // Unireg field length
472
484
(*blob_columns)++;
474
case DRIZZLE_TYPE_VARCHAR:
476
487
case DRIZZLE_TYPE_ENUM:
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_TIME:
486
case DRIZZLE_TYPE_DATETIME:
487
case DRIZZLE_TYPE_NULL:
489
case DRIZZLE_TYPE_DECIMAL:
489
if (check_duplicates_in_interval("ENUM",
490
sql_field->field_name,
500
case DRIZZLE_TYPE_MICROTIME:
491
501
case DRIZZLE_TYPE_TIMESTAMP:
492
502
/* We should replace old TIMESTAMP fields with their newer analogs */
493
503
if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
505
515
else if (sql_field->unireg_check != Field::NONE)
506
517
(*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:
517
static int mysql_prepare_create_table(Session *session,
518
HA_CREATE_INFO *create_info,
519
message::Table &create_proto,
520
AlterInfo *alter_info,
522
uint32_t *db_options,
523
KeyInfo **key_info_buffer,
525
int select_field_count)
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)
527
551
const char *key_name;
528
552
CreateField *sql_field,*dup_field;
964
993
message::Table::Field *protofield= NULL;
966
List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
995
List<Key_part_spec>::iterator cols(key->columns.begin());
996
List<Key_part_spec>::iterator cols2(key->columns.begin());
967
997
for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
970
1000
Key_part_spec *dup_column;
971
1001
int proto_field_nr= 0;
1003
it= alter_info->create_list.begin();
975
1005
while ((sql_field=it++) && ++proto_field_nr &&
976
1006
my_strcasecmp(system_charset_info,
977
1007
column->field_name.str,
978
1008
sql_field->field_name))
982
1015
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
985
1019
while ((dup_column= cols2++) != column)
987
1021
if (!my_strcasecmp(system_charset_info,
1164
1200
key_info->name=(char*) key_name;
1167
1204
if (!key_info->name || check_column_name(key_info->name))
1169
1206
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1172
1210
if (!(key_info->flags & HA_NULL_PART_KEY))
1174
1215
key_info->key_length=(uint16_t) key_length;
1175
1217
if (key_length > max_key_length)
1177
1219
my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1182
1226
if (!unique_key && !primary_key &&
1183
1227
(engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1185
1229
my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1188
1233
if (auto_increment > 0)
1190
1235
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1427
1468
set_table_default_charset(create_info, identifier.getSchemaName().c_str());
1429
1470
/* Build a Table object to pass down to the engine, and the do the actual create. */
1430
if (not mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1433
&key_info_buffer, &key_count,
1434
select_field_count))
1471
if (not prepare_create_table(session, create_info, table_proto, alter_info,
1474
&key_info_buffer, &key_count,
1475
select_field_count))
1436
1477
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1437
1478
error= locked_create_event(session,
1513
Database locking aware wrapper for mysql_create_table_no_lock(),
1552
Database locking aware wrapper for create_table_no_lock(),
1515
bool mysql_create_table(Session *session,
1516
const TableIdentifier &identifier,
1554
bool create_table(Session *session,
1555
const identifier::Table &identifier,
1517
1556
HA_CREATE_INFO *create_info,
1518
1557
message::Table &table_proto,
1519
1558
AlterInfo *alter_info,
1749
1788
item->maybe_null = 1;
1750
1789
field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
1751
1790
item->maybe_null = 1;
1752
if (session->client->sendFields(&field_list))
1791
if (session->getClient()->sendFields(&field_list))
1755
1794
for (table= tables; table; table= table->next_local)
1757
char table_name[NAME_LEN*2+2];
1796
identifier::Table table_identifier(table->getSchemaName(), table->getTableName());
1797
std::string table_name;
1758
1798
bool fatal_error=0;
1760
snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
1800
table_identifier.getSQLPath(table_name);
1761
1802
table->lock_type= lock_type;
1762
1803
/* open only one table from local list of command */
1805
1846
char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1806
1847
uint32_t length;
1807
session->client->store(table_name);
1808
session->client->store(operator_name);
1809
session->client->store(STRING_WITH_LEN("error"));
1848
session->getClient()->store(table_name.c_str());
1849
session->getClient()->store(operator_name);
1850
session->getClient()->store(STRING_WITH_LEN("error"));
1810
1851
length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1812
session->client->store(buff, length);
1813
transaction_services.autocommitOrRollback(session, false);
1852
table_name.c_str());
1853
session->getClient()->store(buff, length);
1854
transaction_services.autocommitOrRollback(*session, false);
1814
1855
session->endTransaction(COMMIT);
1815
1856
session->close_thread_tables();
1816
lex->reset_query_tables_list(false);
1857
session->getLex()->reset_query_tables_list(false);
1817
1858
table->table=0; // For query cache
1818
if (session->client->flush())
1859
if (session->getClient()->flush())
1827
1868
const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1828
1869
"Waiting to get writelock");
1829
1870
session->abortLock(table->table);
1830
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1871
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1831
1872
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1832
1873
session->exit_cond(old_message);
1833
1874
if (session->getKilled())
1842
lex->cleanup_after_one_table_open();
1883
session->getLex()->cleanup_after_one_table_open();
1843
1884
session->clear_error(); // these errors shouldn't get client
1845
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
1886
List<DRIZZLE_ERROR>::iterator it(session->warn_list.begin());
1846
1887
DRIZZLE_ERROR *err;
1847
1888
while ((err= it++))
1849
session->client->store(table_name);
1850
session->client->store(operator_name);
1851
session->client->store(warning_level_names[err->level].str,
1890
session->getClient()->store(table_name.c_str());
1891
session->getClient()->store(operator_name);
1892
session->getClient()->store(warning_level_names[err->level].str,
1852
1893
warning_level_names[err->level].length);
1853
session->client->store(err->msg);
1854
if (session->client->flush())
1894
session->getClient()->store(err->msg);
1895
if (session->getClient()->flush())
1857
1898
drizzle_reset_errors(session, true);
1859
session->client->store(table_name);
1860
session->client->store(operator_name);
1900
session->getClient()->store(table_name.c_str());
1901
session->getClient()->store(operator_name);
1862
1903
switch (result_code) {
1863
1904
case HA_ADMIN_NOT_IMPLEMENTED:
1865
1906
char buf[ERRMSGSIZE+20];
1866
1907
uint32_t length=snprintf(buf, ERRMSGSIZE,
1867
1908
ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
1868
session->client->store(STRING_WITH_LEN("note"));
1869
session->client->store(buf, length);
1909
session->getClient()->store(STRING_WITH_LEN("note"));
1910
session->getClient()->store(buf, length);
1873
1914
case HA_ADMIN_OK:
1874
session->client->store(STRING_WITH_LEN("status"));
1875
session->client->store(STRING_WITH_LEN("OK"));
1915
session->getClient()->store(STRING_WITH_LEN("status"));
1916
session->getClient()->store(STRING_WITH_LEN("OK"));
1878
1919
case HA_ADMIN_FAILED:
1879
session->client->store(STRING_WITH_LEN("status"));
1880
session->client->store(STRING_WITH_LEN("Operation failed"));
1920
session->getClient()->store(STRING_WITH_LEN("status"));
1921
session->getClient()->store(STRING_WITH_LEN("Operation failed"));
1883
1924
case HA_ADMIN_REJECT:
1884
session->client->store(STRING_WITH_LEN("status"));
1885
session->client->store(STRING_WITH_LEN("Operation need committed state"));
1925
session->getClient()->store(STRING_WITH_LEN("status"));
1926
session->getClient()->store(STRING_WITH_LEN("Operation need committed state"));
1886
1927
open_for_modify= false;
1889
1930
case HA_ADMIN_ALREADY_DONE:
1890
session->client->store(STRING_WITH_LEN("status"));
1891
session->client->store(STRING_WITH_LEN("Table is already up to date"));
1931
session->getClient()->store(STRING_WITH_LEN("status"));
1932
session->getClient()->store(STRING_WITH_LEN("Table is already up to date"));
1894
1935
case HA_ADMIN_CORRUPT:
1895
session->client->store(STRING_WITH_LEN("error"));
1896
session->client->store(STRING_WITH_LEN("Corrupt"));
1936
session->getClient()->store(STRING_WITH_LEN("error"));
1937
session->getClient()->store(STRING_WITH_LEN("Corrupt"));
1900
1941
case HA_ADMIN_INVALID:
1901
session->client->store(STRING_WITH_LEN("error"));
1902
session->client->store(STRING_WITH_LEN("Invalid argument"));
1942
session->getClient()->store(STRING_WITH_LEN("error"));
1943
session->getClient()->store(STRING_WITH_LEN("Invalid argument"));
1905
1946
default: // Probably HA_ADMIN_INTERNAL_ERROR
1931
1972
boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1932
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1973
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1933
1974
table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1937
transaction_services.autocommitOrRollback(session, false);
1978
transaction_services.autocommitOrRollback(*session, false);
1938
1979
session->endTransaction(COMMIT);
1939
1980
session->close_thread_tables();
1940
1981
table->table=0; // For query cache
1941
if (session->client->flush())
1982
if (session->getClient()->flush())
1969
2010
during the call to plugin::StorageEngine::createTable().
1970
2011
See bug #28614 for more info.
1972
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1973
const TableIdentifier &destination_identifier,
1974
const TableIdentifier &src_table,
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,
1975
2017
bool is_engine_set)
1977
int protoerr= EEXIST;
1978
message::Table new_proto;
1979
message::table::shared_ptr src_proto;
1981
protoerr= plugin::StorageEngine::getTableDefinition(session,
1984
new_proto.CopyFrom(*src_proto);
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);
1986
2034
if (destination_identifier.isTmp())
1988
new_proto.set_type(message::Table::TEMPORARY);
2036
new_table_message.set_type(message::Table::TEMPORARY);
1992
new_proto.set_type(message::Table::STANDARD);
2040
new_table_message.set_type(message::Table::STANDARD);
1995
2043
if (is_engine_set)
1997
new_proto.mutable_engine()->set_name(create_table_proto.engine().name());
2045
new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
2000
2048
{ // We now do a selective copy of elements on to the new table.
2001
new_proto.set_name(create_table_proto.name());
2002
new_proto.set_schema(create_table_proto.schema());
2003
new_proto.set_catalog(create_table_proto.catalog());
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());
2006
if (protoerr && protoerr != EEXIST)
2054
/* Fix names of foreign keys being added */
2055
for (int32_t j= 0; j < new_table_message.fk_constraint_size(); j++)
2008
if (errno == ENOENT)
2009
my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName().c_str());
2011
my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath().c_str(), errno);
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);
2017
2072
As mysql_truncate don't work on a new table at this stage of
2018
creation, instead create the table directly (for both normal
2019
and temporary tables).
2073
creation, instead create the table directly (for both normal and temporary tables).
2021
int err= plugin::StorageEngine::createTable(session,
2022
destination_identifier,
2075
bool success= plugin::StorageEngine::createTable(session,
2076
destination_identifier,
2025
if (err == false && not destination_identifier.isTmp())
2079
if (success && not destination_identifier.isTmp())
2027
2081
TransactionServices &transaction_services= TransactionServices::singleton();
2028
transaction_services.createTable(&session, new_proto);
2082
transaction_services.createTable(session, new_table_message);
2031
return err ? false : true;
2035
2089
Create a table identical to the specified table
2038
mysql_create_like_table()
2039
2093
session Thread object
2040
2094
table Table list element for target table
2041
2095
src_table Table list element for source table
2049
bool mysql_create_like_table(Session* session,
2050
const TableIdentifier &destination_identifier,
2051
TableList* table, TableList* src_table,
2052
message::Table &create_table_proto,
2053
bool is_if_not_exists,
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,
2056
2110
bool res= true;
2060
By opening source table we guarantee that it exists and no concurrent
2061
DDL operation will mess with it. Later we also take an exclusive
2062
name-lock on target table name, which makes copying of .frm cursor,
2063
call to plugin::StorageEngine::createTable() and binlogging atomic
2064
against concurrent DML and DDL operations on target table.
2065
Thus by holding both these "locks" we ensure that our statement is
2066
properly isolated from all concurrent operations which matter.
2068
if (session->open_tables_from_list(&src_table, ¬_used))
2071
TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
2072
src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
2111
bool table_exists= false;
2077
2114
Check that destination tables does not exist. Note that its name
2163
2202
char warn_buff[DRIZZLE_ERRMSG_SIZE];
2164
2203
snprintf(warn_buff, sizeof(warn_buff),
2165
ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
2204
ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
2166
2205
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2167
ER_TABLE_EXISTS_ERROR,warn_buff);
2172
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
2206
ER_TABLE_EXISTS_ERROR, warn_buff);
2210
my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
2180
bool mysql_analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2219
bool analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2182
2221
thr_lock_type lock_type = TL_READ_NO_INSERT;
2184
return(mysql_admin_table(session, tables, check_opt,
2223
return(admin_table(session, tables, check_opt,
2185
2224
"analyze", lock_type, true,
2186
2225
&Cursor::ha_analyze));
2190
bool mysql_check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
2229
bool check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
2192
2231
thr_lock_type lock_type = TL_READ_NO_INSERT;
2194
return(mysql_admin_table(session, tables, check_opt,
2233
return(admin_table(session, tables, check_opt,
2195
2234
"check", lock_type,
2197
2236
&Cursor::ha_check));