107
107
assert(select_lex->db);
109
109
/* Chicken/Egg... we need to search for the table, to know if the table exists, so we can build a full identifier from it */
110
message::table::shared_ptr original_table_message;
110
message::Table original_table_message;
112
112
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
113
113
if (plugin::StorageEngine::getTableDefinition(*session, identifier, original_table_message) != EEXIST)
116
identifier.getSQLPath(path);
117
my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
115
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
121
119
if (not create_info.db_type)
123
121
create_info.db_type=
124
plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
122
plugin::StorageEngine::findByName(*session, original_table_message.engine().name());
126
124
if (not create_info.db_type)
129
identifier.getSQLPath(path);
130
my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
126
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
136
132
if (not validateCreateTableOption())
139
137
/* ALTER TABLE ends previous transaction */
140
138
if (not session->endActiveTransaction())
143
if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
143
if (not (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
147
if (original_table_message->type() == message::Table::STANDARD )
149
if (original_table_message.type() == message::Table::STANDARD )
149
151
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
150
152
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
191
193
Release the protection against the global read lock and wake
192
194
everyone, who might want to set a global read lock.
194
session->startWaitingGlobalReadLock();
196
start_waiting_global_read_lock(session);
368
367
if (def->change && ! def->field)
370
369
my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->getMutableShare()->getTableName());
374
If we have been given a field which has no default value, and is not null then we need to bail.
373
Check that the DATE/DATETIME not null field we are going to add is
374
either has a default value or the '0000-00-00' is allowed by the
376
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
377
flag to allow ALTER Table only if the table to be altered is empty.
376
if (not (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) and not def->change)
379
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
380
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
381
! alter_info->datetime_field &&
382
! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
384
alter_info->datetime_field= def;
378
385
alter_info->error_if_not_empty= true;
380
387
if (! def->after)
382
388
new_create_list.push_back(def);
384
389
else if (def->after == first_keyword)
386
390
new_create_list.push_front(def);
390
393
CreateField *find;
413
416
if (alter_info->build_method == HA_BUILD_ONLINE)
415
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->getQueryString()->c_str());
418
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query.c_str());
418
421
alter_info->build_method= HA_BUILD_OFFLINE;
425
428
alter_info->alter_list.head()->name,
426
429
table->getMutableShare()->getTableName());
429
432
if (! new_create_list.elements)
431
434
my_message(ER_CANT_REMOVE_ALL_FIELDS,
432
435
ER(ER_CANT_REMOVE_ALL_FIELDS),
568
571
if (key->type == Key::FOREIGN_KEY)
570
573
if (((Foreign_key *)key)->validate(new_create_list))
575
576
Foreign_key *fkey= (Foreign_key*)key;
576
577
add_foreign_key_to_table_message(&table_message,
618
619
my_error(ER_CANT_DROP_FIELD_OR_KEY,
620
621
alter_info->drop_list.head()->name);
623
624
if (alter_info->alter_list.elements)
625
626
my_error(ER_CANT_DROP_FIELD_OR_KEY,
627
628
alter_info->alter_list.head()->name);
631
632
if (not table_message.options().has_comment()
645
646
alter_info->create_list.swap(new_create_list);
646
647
alter_info->key_list.swap(new_key_list);
648
650
size_t num_engine_options= table_message.engine().options_size();
649
651
size_t original_num_engine_options= original_proto.engine().options_size();
713
715
/* The ALTER Table is always in its own transaction */
714
716
error= transaction_services.autocommitOrRollback(session, false);
715
if (not session->endActiveTransaction())
717
if (! session->endActiveTransaction())
721
write_bin_log(session, *session->getQueryString());
721
write_bin_log(session, session->query.c_str());
724
724
(void) transaction_services.autocommitOrRollback(session, error);
792
792
if (session.find_temporary_table(new_table_identifier))
795
new_table_identifier.getSQLPath(path);
796
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
794
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
807
805
if (not name_lock)
810
new_table_identifier.getSQLPath(path);
811
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
807
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
815
811
if (plugin::StorageEngine::doesTableExist(session, new_table_identifier))
818
new_table_identifier.getSQLPath(path);
820
813
/* Table will be closed by Session::executeCommand() */
821
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
814
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
823
table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
816
LOCK_open.lock(); /* ALTER TABLe */
824
817
session.unlink_open_table(name_lock);
825
table::Cache::singleton().mutex().unlock();
934
921
if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
935
922
new_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
938
new_table_identifier.getSQLPath(path);
939
my_error(ER_ILLEGAL_HA, MYF(0), path.c_str());
924
my_error(ER_ILLEGAL_HA, MYF(0), new_table_identifier.getSQLPath().c_str());
970
955
while the fact that the table is still open gives us protection
971
956
from concurrent DDL statements.
973
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
958
LOCK_open.lock(); /* DDL wait for/blocker */
974
959
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
975
table::Cache::singleton().mutex().unlock();
976
961
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
977
962
/* COND_refresh will be signaled in close_thread_tables() */
980
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
965
LOCK_open.lock(); /* DDL wait for/blocker */
981
966
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
982
table::Cache::singleton().mutex().unlock();
983
968
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
984
969
/* COND_refresh will be signaled in close_thread_tables() */
997
982
table->getAlias());
1000
table::Cache::singleton().mutex().lock(); /* Lock to remove all instances of table from table cache before ALTER */
985
LOCK_open.lock(); /* Lock to remove all instances of table from table cache before ALTER */
1002
987
Unlike to the above case close_cached_table() below will remove ALL
1003
988
instances of Table from table cache (it will also remove table lock
1004
989
held by this thread). So to make actual table renaming and writing
1005
990
to binlog atomic we have to put them into the same critical section
1006
protected by table::Cache::singleton().mutex() mutex. This also removes gap for races between
991
protected by LOCK_open mutex. This also removes gap for races between
1007
992
access() and mysql_rename_table() calls.
1026
1011
if (plugin::StorageEngine::doesTableExist(*session, new_table_identifier))
1029
new_table_identifier.getSQLPath(path);
1030
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1013
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
1050
1033
if (error == 0)
1052
TransactionServices &transaction_services= TransactionServices::singleton();
1053
transaction_services.allocateNewTransactionId();
1054
write_bin_log(session, *session->getQueryString());
1035
write_bin_log(session, session->query.c_str());
1055
1036
session->my_ok();
1057
1038
else if (error > 0)
1150
1131
if (alter_info->error_if_not_empty && session->row_count)
1152
my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
1133
const char *f_val= 0;
1134
enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1136
switch (alter_info->datetime_field->sql_type)
1138
case DRIZZLE_TYPE_DATE:
1139
f_val= "0000-00-00";
1140
t_type= DRIZZLE_TIMESTAMP_DATE;
1142
case DRIZZLE_TYPE_DATETIME:
1143
f_val= "0000-00-00 00:00:00";
1144
t_type= DRIZZLE_TIMESTAMP_DATETIME;
1147
/* Shouldn't get here. */
1150
bool save_abort_on_warning= session->abort_on_warning;
1151
session->abort_on_warning= true;
1152
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1153
f_val, internal::strlength(f_val), t_type,
1154
alter_info->datetime_field->field_name);
1155
session->abort_on_warning= save_abort_on_warning;
1155
1158
if (original_table_identifier.isTmp())
1183
1186
delete new_table;
1186
table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
1189
LOCK_open.lock(); /* ALTER TABLE */
1188
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1189
table::Cache::singleton().mutex().unlock();
1191
quick_rm_table(*session, new_table_as_temporary);
1278
1281
if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1281
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1284
quick_rm_table(*session, new_table_as_temporary);
1287
1290
/* Try to get everything back. */
1290
plugin::StorageEngine::dropTable(*session, new_table_identifier);
1293
quick_rm_table(*session, new_table_identifier);
1292
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1295
quick_rm_table(*session, new_table_as_temporary);
1294
1297
mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1298
plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1301
quick_rm_table(*session, original_table_to_drop);
1307
1310
from list of open tables list and table cache.
1309
1312
session->unlink_open_table(table);
1310
table::Cache::singleton().mutex().unlock();
1315
table::Cache::singleton().mutex().unlock();
1317
1320
session->set_proc_info("end");
1319
write_bin_log(session, *session->getQueryString());
1322
write_bin_log(session, session->query.c_str());
1320
1323
table_list->table= NULL;
1441
1444
* LP Bug #552420
1443
* Since open_temporary_table() doesn't invoke lockTables(), we
1446
* Since open_temporary_table() doesn't invoke mysql_lock_tables(), we
1444
1447
* don't get the usual automatic call to StorageEngine::startStatement(), so
1445
1448
* we manually call it here...
1546
1549
to->next_number_field->reset();
1549
for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
1552
for (CopyField *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
1551
if (not copy->to_field->hasDefault() and copy->from_null_ptr and *copy->from_null_ptr & copy->from_bit)
1553
copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
1554
ER_WARN_DATA_TRUNCATED, 1);
1555
copy->to_field->reset();
1560
1554
copy_ptr->do_copy(copy_ptr);
1568
1556
prev_insert_id= to->cursor->next_insert_id;
1569
1557
error= to->cursor->insertRecord(to->record[0]);
1570
1558
to->auto_increment_field_not_null= false;
1574
if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1563
to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1576
1565
to->print_error(error, MYF(0));