107
103
assert(select_lex->db);
109
105
/* 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;
106
message::Table original_table_message;
112
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
108
TableIdentifier identifier(first_table->db, first_table->table_name);
113
109
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());
111
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
121
115
if (not create_info.db_type)
123
117
create_info.db_type=
124
plugin::StorageEngine::findByName(*session, original_table_message->engine().name());
118
plugin::StorageEngine::findByName(*session, original_table_message.engine().name());
126
120
if (not create_info.db_type)
129
identifier.getSQLPath(path);
130
my_error(ER_BAD_TABLE_ERROR, MYF(0), path.c_str());
122
my_error(ER_BAD_TABLE_ERROR, MYF(0), identifier.getSQLPath().c_str());
136
128
if (not validateCreateTableOption())
139
133
/* ALTER TABLE ends previous transaction */
140
134
if (not session->endActiveTransaction())
143
if (not (need_start_waiting= not session->wait_if_global_read_lock(0, 1)))
139
if (not (need_start_waiting= ! wait_if_global_read_lock(session, 0, 1)))
147
if (original_table_message->type() == message::Table::STANDARD )
145
if (original_table_message.type() == message::Table::STANDARD )
149
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName());
150
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
151
session->lex->name.str ? session->lex->name.str : first_table->getTableName());
147
TableIdentifier identifier(first_table->db, first_table->table_name);
148
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
149
session->lex->name.str ? session->lex->name.str : first_table->table_name);
153
151
res= alter_table(session,
157
*original_table_message,
155
original_table_message,
158
156
create_table_message,
161
159
select_lex->order_list.elements,
162
(Order *) select_lex->order_list.first,
160
(order_st *) select_lex->order_list.first,
163
161
session->lex->ignore);
167
TableIdentifier catch22(first_table->getSchemaName(), first_table->getTableName());
168
Table *table= session->find_temporary_table(catch22);
165
Table *table= session->find_temporary_table(first_table);
171
TableIdentifier identifier(first_table->getSchemaName(), first_table->getTableName(), table->getMutableShare()->getPath());
172
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->getSchemaName(),
173
session->lex->name.str ? session->lex->name.str : first_table->getTableName(),
168
TableIdentifier identifier(first_table->db, first_table->table_name, table->getMutableShare()->getPath());
169
TableIdentifier new_identifier(select_lex->db ? select_lex->db : first_table->db,
170
session->lex->name.str ? session->lex->name.str : first_table->table_name,
174
171
table->getMutableShare()->getPath());
176
173
res= alter_table(session,
180
*original_table_message,
177
original_table_message,
181
178
create_table_message,
184
181
select_lex->order_list.elements,
185
(Order *) select_lex->order_list.first,
182
(order_st *) select_lex->order_list.first,
186
183
session->lex->ignore);
368
360
if (def->change && ! def->field)
370
362
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.
366
Check that the DATE/DATETIME not null field we are going to add is
367
either has a default value or the '0000-00-00' is allowed by the
369
If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
370
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)
372
if ((def->sql_type == DRIZZLE_TYPE_DATE ||
373
def->sql_type == DRIZZLE_TYPE_DATETIME) &&
374
! alter_info->datetime_field &&
375
! (~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)))
377
alter_info->datetime_field= def;
378
378
alter_info->error_if_not_empty= true;
380
380
if (! def->after)
382
381
new_create_list.push_back(def);
384
382
else if (def->after == first_keyword)
386
383
new_create_list.push_front(def);
390
386
CreateField *find;
537
533
new_key_list.push_back(key);
541
/* Copy over existing foreign keys */
542
for (int j= 0; j < original_proto.fk_constraint_size(); j++)
546
while ((drop= drop_it++))
548
if (drop->type == AlterDrop::FOREIGN_KEY &&
549
! my_strcasecmp(system_charset_info, original_proto.fk_constraint(j).name().c_str(), drop->name))
560
message::Table::ForeignKeyConstraint *pfkey= table_message.add_fk_constraint();
561
*pfkey= original_proto.fk_constraint(j);
566
538
while ((key= key_it++)) /* Add new keys */
568
if (key->type == Key::FOREIGN_KEY)
570
if (((Foreign_key *)key)->validate(new_create_list))
575
Foreign_key *fkey= (Foreign_key*)key;
576
add_foreign_key_to_table_message(&table_message,
540
if (key->type == Key::FOREIGN_KEY &&
541
((Foreign_key *)key)->validate(new_create_list))
586
543
if (key->type != Key::FOREIGN_KEY)
587
544
new_key_list.push_back(key);
589
545
if (key->name.str && is_primary_key_name(key->name.str))
591
547
my_error(ER_WRONG_NAME_FOR_INDEX,
599
/* Fix names of foreign keys being added */
600
for (int j= 0; j < table_message.fk_constraint_size(); j++)
602
if (! table_message.fk_constraint(j).has_name())
604
std::string name(table->getMutableShare()->getTableName());
607
name.append("_ibfk_");
608
snprintf(number, sizeof(number), "%d", j+1);
611
message::Table::ForeignKeyConstraint *pfkey= table_message.mutable_fk_constraint(j);
612
pfkey->set_name(name);
616
555
if (alter_info->drop_list.elements)
618
557
my_error(ER_CANT_DROP_FIELD_OR_KEY,
620
559
alter_info->drop_list.head()->name);
623
562
if (alter_info->alter_list.elements)
625
564
my_error(ER_CANT_DROP_FIELD_OR_KEY,
627
566
alter_info->alter_list.head()->name);
631
570
if (not table_message.options().has_comment()
807
741
if (not name_lock)
810
new_table_identifier.getSQLPath(path);
811
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
743
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
815
747
if (plugin::StorageEngine::doesTableExist(session, new_table_identifier))
818
new_table_identifier.getSQLPath(path);
820
749
/* Table will be closed by Session::executeCommand() */
821
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
750
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
823
table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
752
pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
824
753
session.unlink_open_table(name_lock);
825
table::Cache::singleton().mutex().unlock();
754
pthread_mutex_unlock(&LOCK_open);
934
860
if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
935
861
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());
863
my_error(ER_ILLEGAL_HA, MYF(0), new_table_identifier.getSQLPath().c_str());
868
if (create_info->row_type == ROW_TYPE_NOT_USED)
870
message::Table::TableOptions *table_options;
871
table_options= create_proto.mutable_options();
873
create_info->row_type= table->getShare()->row_type;
874
table_options->set_row_type(original_table_definition->options().row_type());
944
877
session->set_proc_info("setup");
970
903
while the fact that the table is still open gives us protection
971
904
from concurrent DDL statements.
973
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
906
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
974
907
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
975
table::Cache::singleton().mutex().unlock();
908
pthread_mutex_unlock(&LOCK_open);
976
909
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
977
910
/* COND_refresh will be signaled in close_thread_tables() */
980
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
913
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
981
914
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
982
table::Cache::singleton().mutex().unlock();
915
pthread_mutex_unlock(&LOCK_open);
983
916
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
984
917
/* COND_refresh will be signaled in close_thread_tables() */
995
928
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
996
929
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1000
table::Cache::singleton().mutex().lock(); /* Lock to remove all instances of table from table cache before ALTER */
933
pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
1002
935
Unlike to the above case close_cached_table() below will remove ALL
1003
936
instances of Table from table cache (it will also remove table lock
1004
937
held by this thread). So to make actual table renaming and writing
1005
938
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
939
protected by LOCK_open mutex. This also removes gap for races between
1007
940
access() and mysql_rename_table() calls.
1102
1031
/* Open the table so we need to copy the data to it. */
1103
Table *new_table= open_alter_table(session, table, new_table_as_temporary);
1032
new_table= open_alter_table(session, table, new_table_as_temporary);
1106
1034
if (not new_table)
1108
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1036
quick_rm_table(*session, new_table_as_temporary);
1112
1040
/* Copy the data if necessary. */
1114
/* We must not ignore bad input! */
1115
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; // calc cuted fields
1042
session->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
1116
1043
session->cuted_fields= 0L;
1117
1044
session->set_proc_info("copy to tmp table");
1118
1045
copied= deleted= 0;
1150
1077
if (alter_info->error_if_not_empty && session->row_count)
1152
my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
1079
const char *f_val= 0;
1080
enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1082
switch (alter_info->datetime_field->sql_type)
1084
case DRIZZLE_TYPE_DATE:
1085
f_val= "0000-00-00";
1086
t_type= DRIZZLE_TIMESTAMP_DATE;
1088
case DRIZZLE_TYPE_DATETIME:
1089
f_val= "0000-00-00 00:00:00";
1090
t_type= DRIZZLE_TIMESTAMP_DATETIME;
1093
/* Shouldn't get here. */
1096
bool save_abort_on_warning= session->abort_on_warning;
1097
session->abort_on_warning= true;
1098
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1099
f_val, internal::strlength(f_val), t_type,
1100
alter_info->datetime_field->field_name);
1101
session->abort_on_warning= save_abort_on_warning;
1155
1104
if (original_table_identifier.isTmp())
1177
1126
new_table->intern_close_table();
1178
1127
if (new_table->hasShare())
1180
delete new_table->getMutableShare();
1129
assert(new_table->getShare()->newed);
1130
delete new_table->s;
1186
table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
1137
pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1188
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1189
table::Cache::singleton().mutex().unlock();
1139
quick_rm_table(*session, new_table_as_temporary);
1140
pthread_mutex_unlock(&LOCK_open);
1272
1225
compare_table(). Then, we need one additional call to
1274
1227
TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1275
old_name, create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1276
message::Table::TEMPORARY);
1228
old_name, message::Table::TEMPORARY);
1278
1230
if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1281
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1233
quick_rm_table(*session, new_table_as_temporary);
1287
1239
/* Try to get everything back. */
1290
plugin::StorageEngine::dropTable(*session, new_table_identifier);
1242
quick_rm_table(*session, new_table_identifier);
1292
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1244
quick_rm_table(*session, new_table_as_temporary);
1294
1246
mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1298
plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1250
quick_rm_table(*session, original_table_to_drop);
1496
FileSort filesort(*session);
1497
1448
from->sort.io_cache= new internal::IO_CACHE;
1499
1450
memset(&tables, 0, sizeof(tables));
1500
1451
tables.table= from;
1501
tables.setTableName(const_cast<char *>(from->getMutableShare()->getTableName()));
1502
tables.alias= const_cast<char *>(tables.getTableName());
1503
tables.setSchemaName(const_cast<char *>(from->getMutableShare()->getSchemaName()));
1452
tables.alias= tables.table_name= const_cast<char *>(from->getMutableShare()->getTableName());
1453
tables.db= const_cast<char *>(from->getMutableShare()->getSchemaName());
1506
1456
if (session->lex->select_lex.setup_ref_array(session, order_num) ||
1507
1457
setup_order(session, session->lex->select_lex.ref_pointer_array,
1508
1458
&tables, fields, all_fields, order) ||
1509
1459
!(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)
1460
(from->sort.found_records= filesort(session, from, sortorder, length,
1461
(optimizer::SqlSelect *) 0, HA_POS_ERROR,
1462
1, &examined_rows)) ==
1546
1497
to->next_number_field->reset();
1549
for (CopyField *copy_ptr= copy; copy_ptr != copy_end ; copy_ptr++)
1500
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
1502
copy_ptr->do_copy(copy_ptr);
1568
1504
prev_insert_id= to->cursor->next_insert_id;
1569
1505
error= to->cursor->insertRecord(to->record[0]);
1570
1506
to->auto_increment_field_not_null= false;
1574
if (!ignore || to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1511
to->cursor->is_fatal_error(error, HA_CHECK_DUP))
1576
1513
to->print_error(error, MYF(0));