107
105
assert(select_lex->db);
109
107
/* 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;
108
message::Table original_table_message;
112
110
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
113
111
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());
113
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
121
117
if (not create_info.db_type)
123
119
create_info.db_type=
124
plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
120
plugin::StorageEngine::findByName(*session, original_table_message.engine().name());
126
122
if (not create_info.db_type)
129
identifier.getSQLPath(path);
130
my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
124
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
136
130
if (not validateCreateTableOption())
139
135
/* ALTER TABLE ends previous transaction */
140
136
if (not session->endActiveTransaction())
143
if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
141
if (not (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
147
if (original_table_message->type() == message::Table::STANDARD )
147
if (original_table_message.type() == message::Table::STANDARD )
149
149
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
150
150
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
157
*original_table_message,
157
original_table_message,
158
158
create_table_message,
161
161
select_lex->order_list.elements,
162
(Order *) select_lex->order_list.first,
162
(order_st *) select_lex->order_list.first,
163
163
session->lex->ignore);
180
*original_table_message,
180
original_table_message,
181
181
create_table_message,
184
184
select_lex->order_list.elements,
185
(Order *) select_lex->order_list.first,
185
(order_st *) select_lex->order_list.first,
186
186
session->lex->ignore);
191
191
Release the protection against the global read lock and wake
192
192
everyone, who might want to set a global read lock.
194
session->startWaitingGlobalReadLock();
194
start_waiting_global_read_lock(session);
368
365
if (def->change && ! def->field)
370
367
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.
371
Check that the DATE/DATETIME not null field we are going to add is
372
either has a default value or the '0000-00-00' is allowed by the
374
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
375
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)
377
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
378
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
379
! alter_info->datetime_field &&
380
! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
382
alter_info->datetime_field= def;
378
383
alter_info->error_if_not_empty= true;
380
385
if (! def->after)
382
386
new_create_list.push_back(def);
384
387
else if (def->after == first_keyword)
386
388
new_create_list.push_front(def);
390
391
CreateField *find;
413
414
if (alter_info->build_method == HA_BUILD_ONLINE)
415
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->getQueryString()->c_str());
416
my_error(ER_NOT_SUPPORTED_YET, MYF(0), session->query.c_str());
418
419
alter_info->build_method= HA_BUILD_OFFLINE;
425
426
alter_info->alter_list.head()->name,
426
427
table->getMutableShare()->getTableName());
429
430
if (! new_create_list.elements)
431
432
my_message(ER_CANT_REMOVE_ALL_FIELDS,
432
433
ER(ER_CANT_REMOVE_ALL_FIELDS),
568
569
if (key->type == Key::FOREIGN_KEY)
570
571
if (((Foreign_key *)key)->validate(new_create_list))
575
574
Foreign_key *fkey= (Foreign_key*)key;
576
575
add_foreign_key_to_table_message(&table_message,
618
617
my_error(ER_CANT_DROP_FIELD_OR_KEY,
620
619
alter_info->drop_list.head()->name);
623
622
if (alter_info->alter_list.elements)
625
624
my_error(ER_CANT_DROP_FIELD_OR_KEY,
627
626
alter_info->alter_list.head()->name);
631
630
if (not table_message.options().has_comment()
645
644
alter_info->create_list.swap(new_create_list);
646
645
alter_info->key_list.swap(new_key_list);
648
648
size_t num_engine_options= table_message.engine().options_size();
649
649
size_t original_num_engine_options= original_proto.engine().options_size();
713
713
/* The ALTER Table is always in its own transaction */
714
714
error= transaction_services.autocommitOrRollback(session, false);
715
if (not session->endActiveTransaction())
715
if (! session->endActiveTransaction())
721
write_bin_log(session, *session->getQueryString());
719
write_bin_log(session, session->query.c_str());
724
722
(void) transaction_services.autocommitOrRollback(session, error);
792
790
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());
792
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
807
803
if (not name_lock)
810
new_table_identifier.getSQLPath(path);
811
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
805
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
815
809
if (plugin::StorageEngine::doesTableExist(session, new_table_identifier))
818
new_table_identifier.getSQLPath(path);
820
811
/* Table will be closed by Session::executeCommand() */
821
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
812
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
823
table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
814
LOCK_open.lock(); /* ALTER TABLe */
824
815
session.unlink_open_table(name_lock);
825
table::Cache::singleton().mutex().unlock();
934
919
if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
935
920
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());
922
my_error(ER_ILLEGAL_HA, MYF(0), new_table_identifier.getSQLPath().c_str());
970
953
while the fact that the table is still open gives us protection
971
954
from concurrent DDL statements.
973
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
956
LOCK_open.lock(); /* DDL wait for/blocker */
974
957
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
975
table::Cache::singleton().mutex().unlock();
976
959
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
977
960
/* COND_refresh will be signaled in close_thread_tables() */
980
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
963
LOCK_open.lock(); /* DDL wait for/blocker */
981
964
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
982
table::Cache::singleton().mutex().unlock();
983
966
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
984
967
/* COND_refresh will be signaled in close_thread_tables() */
997
980
table->getAlias());
1000
table::Cache::singleton().mutex().lock(); /* Lock to remove all instances of table from table cache before ALTER */
983
LOCK_open.lock(); /* Lock to remove all instances of table from table cache before ALTER */
1002
985
Unlike to the above case close_cached_table() below will remove ALL
1003
986
instances of Table from table cache (it will also remove table lock
1004
987
held by this thread). So to make actual table renaming and writing
1005
988
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
989
protected by LOCK_open mutex. This also removes gap for races between
1007
990
access() and mysql_rename_table() calls.
1026
1009
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());
1011
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
1050
1031
if (error == 0)
1052
TransactionServices &transaction_services= TransactionServices::singleton();
1053
transaction_services.allocateNewTransactionId();
1054
write_bin_log(session, *session->getQueryString());
1033
write_bin_log(session, session->query.c_str());
1055
1034
session->my_ok();
1057
1036
else if (error > 0)
1150
1129
if (alter_info->error_if_not_empty && session->row_count)
1152
my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
1131
const char *f_val= 0;
1132
enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1134
switch (alter_info->datetime_field->sql_type)
1136
case DRIZZLE_TYPE_DATE:
1137
f_val= "0000-00-00";
1138
t_type= DRIZZLE_TIMESTAMP_DATE;
1140
case DRIZZLE_TYPE_DATETIME:
1141
f_val= "0000-00-00 00:00:00";
1142
t_type= DRIZZLE_TIMESTAMP_DATETIME;
1145
/* Shouldn't get here. */
1148
bool save_abort_on_warning= session->abort_on_warning;
1149
session->abort_on_warning= true;
1150
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1151
f_val, internal::strlength(f_val), t_type,
1152
alter_info->datetime_field->field_name);
1153
session->abort_on_warning= save_abort_on_warning;
1155
1156
if (original_table_identifier.isTmp())
1183
1184
delete new_table;
1186
table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
1187
LOCK_open.lock(); /* ALTER TABLE */
1188
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1189
table::Cache::singleton().mutex().unlock();
1189
quick_rm_table(*session, new_table_as_temporary);
1278
1279
if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1281
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1282
quick_rm_table(*session, new_table_as_temporary);
1287
1288
/* Try to get everything back. */
1290
plugin::StorageEngine::dropTable(*session, new_table_identifier);
1291
quick_rm_table(*session, new_table_identifier);
1292
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1293
quick_rm_table(*session, new_table_as_temporary);
1294
1295
mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1298
plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1299
quick_rm_table(*session, original_table_to_drop);
1307
1308
from list of open tables list and table cache.
1309
1310
session->unlink_open_table(table);
1310
table::Cache::singleton().mutex().unlock();
1315
table::Cache::singleton().mutex().unlock();
1317
1318
session->set_proc_info("end");
1319
write_bin_log(session, *session->getQueryString());
1320
write_bin_log(session, session->query.c_str());
1320
1321
table_list->table= NULL;
1410
1411
Table *from, Table *to,
1411
1412
List<CreateField> &create,
1413
uint32_t order_num, Order *order,
1414
uint32_t order_num, order_st *order,
1414
1415
ha_rows *copied,
1415
1416
ha_rows *deleted,
1416
1417
enum enum_enable_or_disable keys_onoff,
1441
1442
* LP Bug #552420
1443
* Since open_temporary_table() doesn't invoke lockTables(), we
1444
* Since open_temporary_table() doesn't invoke mysql_lock_tables(), we
1444
1445
* don't get the usual automatic call to StorageEngine::startStatement(), so
1445
1446
* we manually call it here...
1507
1507
setup_order(session, session->lex->select_lex.ref_pointer_array,
1508
1508
&tables, fields, all_fields, order) ||
1509
1509
!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
1510
(from->sort.found_records= filesort.run(from, sortorder, length,
1511
(optimizer::SqlSelect *) 0, HA_POS_ERROR,
1512
1, examined_rows)) == HA_POS_ERROR)
1510
(from->sort.found_records= filesort(session, from, sortorder, length,
1511
(optimizer::SqlSelect *) 0, HA_POS_ERROR,
1512
1, &examined_rows)) ==
1546
1547
to->next_number_field->reset();
1549
for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
1550
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
1552
copy_ptr->do_copy(copy_ptr);
1568
1554
prev_insert_id= to->cursor->next_insert_id;
1569
1555
error= to->cursor->insertRecord(to->record[0]);
1570
1556
to->auto_increment_field_not_null= false;
1574
if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1561
to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1576
1563
to->print_error(error, MYF(0));