877
static bool internal_alter_table(Session *session,
879
TableIdentifier &original_table_identifier,
880
TableIdentifier &new_table_identifier,
881
HA_CREATE_INFO *create_info,
882
const message::Table &original_proto,
883
message::Table &create_proto,
884
TableList *table_list,
885
AlterInfo *alter_info,
678
bool alter_table(Session *session,
681
HA_CREATE_INFO *create_info,
682
message::Table *create_proto,
683
TableList *table_list,
684
AlterInfo *alter_info,
690
Table *new_table= NULL;
691
Table *name_lock= NULL;
891
694
char tmp_name[80];
892
695
char old_name[32];
696
char new_name_buff[FN_REFLEN];
697
char new_alias_buff[FN_REFLEN];
700
const char *new_alias;
893
701
ha_rows copied= 0;
894
702
ha_rows deleted= 0;
896
if (not original_table_identifier.isValid())
899
if (not new_table_identifier.isValid())
703
plugin::StorageEngine *old_db_type;
704
plugin::StorageEngine *new_db_type;
705
plugin::StorageEngine *save_old_db_type;
708
new_name_buff[0]= '\0';
711
* @todo this is a result of retaining the behavior that was here before. This should be removed
712
* and the correct error handling should be done in doDropTable for the I_S engine.
714
plugin::InfoSchemaTable *sch_table= plugin::InfoSchemaTable::getTable(table_list->table_name);
717
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
902
721
session->set_proc_info("init");
724
Assign variables table_name, new_name, db, new_db, path
725
to simplify further comparisons: we want to see if it's a RENAME
726
later just by comparing the pointers, avoiding the need for strcmp.
728
table_name= table_list->table_name;
730
if (! new_db || ! my_strcasecmp(table_alias_charset, new_db, db))
733
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
735
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
736
return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
740
oss << drizzle_data_home << "/" << db << "/" << table_name;
742
(void) internal::unpack_filename(new_name_buff, oss.str().c_str());
745
If this is just a rename of a view, short cut to the
746
following scenario: 1) lock LOCK_open 2) do a RENAME
748
This is a copy-paste added to make sure
749
ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
750
as an independent branch in mysql_execute_command. The need
751
for a copy-paste arose because the main code flow of ALTER Table
752
... RENAME tries to use openTableLock, which does not work for views
753
(openTableLock was never modified to merge table lists of child tables
754
into the main table list, like open_tables does).
755
This code is wrong and will be removed, please do not copy.
758
if (!(table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
904
761
table->use_all_columns();
906
plugin::StorageEngine *new_engine;
907
plugin::StorageEngine *original_engine;
909
original_engine= table->getMutableShare()->getEngine();
911
if (not create_info->db_type)
913
create_info->db_type= original_engine;
915
new_engine= create_info->db_type;
918
create_proto.set_schema(new_table_identifier.getSchemaName());
919
create_proto.set_type(new_table_identifier.getType());
922
@todo Have a check on the table definition for FK in the future
923
to remove the need for the cursor. (aka can_switch_engines())
925
if (new_engine != original_engine &&
926
not table->cursor->can_switch_engines())
763
/* Check that we are not trying to rename to an existing table */
766
strcpy(new_name_buff, new_name);
767
strcpy(new_alias_buff, new_name);
768
new_alias= new_alias_buff;
770
my_casedn_str(files_charset_info, new_name_buff);
771
new_alias= new_name; // Create lower case table name
772
my_casedn_str(files_charset_info, new_name);
775
! my_strcasecmp(table_alias_charset, new_name_buff, table_name))
778
Source and destination table names are equal: make later check
781
new_alias= new_name= table_name;
785
if (table->s->tmp_table != NO_TMP_TABLE)
787
if (session->find_temporary_table(new_db, new_name_buff))
789
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
795
if (session->lock_table_name_if_not_cached(new_db, new_name, &name_lock))
800
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
804
build_table_filename(new_name_buff, sizeof(new_name_buff), new_db, new_name_buff, false);
806
if (plugin::StorageEngine::getTableDefinition(*session, new_name_buff, new_db, new_name_buff, false) == EEXIST)
808
/* Table will be closed by Session::executeCommand() */
809
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
817
new_alias= table_name;
818
new_name= table_name;
821
old_db_type= table->s->db_type();
822
if (! create_info->db_type)
824
create_info->db_type= old_db_type;
827
if (table->s->tmp_table != NO_TMP_TABLE)
829
create_proto->set_type(message::Table::TEMPORARY);
833
create_proto->set_type(message::Table::STANDARD);
836
new_db_type= create_info->db_type;
838
if (new_db_type != old_db_type &&
839
!table->cursor->can_switch_engines())
929
842
my_error(ER_ROW_IS_REFERENCED, MYF(0));
934
if (original_engine->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
935
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());
846
if (create_info->row_type == ROW_TYPE_NOT_USED)
848
message::Table::TableOptions *table_options;
849
table_options= create_proto->mutable_options();
851
create_info->row_type= table->s->row_type;
852
table_options->set_row_type((message::Table_TableOptions_RowType)table->s->row_type);
855
if (old_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
856
new_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
858
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
944
862
session->set_proc_info("setup");
947
865
* test if no other bits except ALTER_RENAME and ALTER_KEYS_ONOFF are set
868
tmp.reset(ALTER_RENAME);
869
tmp.reset(ALTER_KEYS_ONOFF);
870
tmp&= alter_info->flags;
872
! table->s->tmp_table) // no need to touch frm
953
tmp.reset(ALTER_RENAME);
954
tmp.reset(ALTER_KEYS_ONOFF);
955
tmp&= alter_info->flags;
957
if (! (tmp.any()) && ! table->getShare()->getType()) // no need to touch frm
959
switch (alter_info->keys_onoff)
965
wait_while_table_is_used() ensures that table being altered is
966
opened only by this thread and that Table::TableShare::version
967
of Table object corresponding to this table is 0.
968
The latter guarantees that no DML statement will open this table
969
until ALTER Table finishes (i.e. until close_thread_tables())
970
while the fact that the table is still open gives us protection
971
from concurrent DDL statements.
973
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
974
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
975
table::Cache::singleton().mutex().unlock();
976
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
977
/* COND_refresh will be signaled in close_thread_tables() */
980
table::Cache::singleton().mutex().lock(); /* DDL wait for/blocker */
981
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
982
table::Cache::singleton().mutex().unlock();
983
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
984
/* COND_refresh will be signaled in close_thread_tables() */
992
if (error == HA_ERR_WRONG_COMMAND)
995
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
996
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 */
1002
Unlike to the above case close_cached_table() below will remove ALL
1003
instances of Table from table cache (it will also remove table lock
1004
held by this thread). So to make actual table renaming and writing
1005
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
1007
access() and mysql_rename_table() calls.
1010
if (error == 0 && not (original_table_identifier == new_table_identifier))
1012
session->set_proc_info("rename");
1014
Then do a 'simple' rename of the table. First we need to close all
1015
instances of 'source' table.
1017
session->close_cached_table(table);
1019
Then, we want check once again that target table does not exist.
1020
Actually the order of these two steps does not matter since
1021
earlier we took name-lock on the target table, so we do them
1022
in this particular order only to be consistent with 5.0, in which
1023
we don't take this name-lock and where this order really matters.
1024
@todo Investigate if we need this access() check at all.
1026
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());
874
switch (alter_info->keys_onoff)
880
wait_while_table_is_used() ensures that table being altered is
881
opened only by this thread and that Table::TableShare::version
882
of Table object corresponding to this table is 0.
883
The latter guarantees that no DML statement will open this table
884
until ALTER Table finishes (i.e. until close_thread_tables())
885
while the fact that the table is still open gives us protection
886
from concurrent DDL statements.
888
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
889
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
890
pthread_mutex_unlock(&LOCK_open);
891
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
892
/* COND_refresh will be signaled in close_thread_tables() */
895
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
896
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
897
pthread_mutex_unlock(&LOCK_open);
898
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
899
/* COND_refresh will be signaled in close_thread_tables() */
907
if (error == HA_ERR_WRONG_COMMAND)
910
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
911
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
915
pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
917
Unlike to the above case close_cached_table() below will remove ALL
918
instances of Table from table cache (it will also remove table lock
919
held by this thread). So to make actual table renaming and writing
920
to binlog atomic we have to put them into the same critical section
921
protected by LOCK_open mutex. This also removes gap for races between
922
access() and mysql_rename_table() calls.
926
(new_name != table_name || new_db != db))
928
session->set_proc_info("rename");
930
Then do a 'simple' rename of the table. First we need to close all
931
instances of 'source' table.
933
session->close_cached_table(table);
935
Then, we want check once again that target table does not exist.
936
Actually the order of these two steps does not matter since
937
earlier we took name-lock on the target table, so we do them
938
in this particular order only to be consistent with 5.0, in which
939
we don't take this name-lock and where this order really matters.
940
TODO: Investigate if we need this access() check at all.
942
if (plugin::StorageEngine::getTableDefinition(*session, new_name, db, table_name, false) == EEXIST)
944
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
949
*internal::fn_ext(new_name)= 0;
950
if (mysql_rename_table(old_db_type, db, table_name, new_db, new_alias, 0))
1035
if (mysql_rename_table(*session, original_engine, original_table_identifier, new_table_identifier))
1042
if (error == HA_ERR_WRONG_COMMAND)
1045
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1046
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
1052
TransactionServices &transaction_services= TransactionServices::singleton();
1053
transaction_services.allocateNewTransactionId();
1054
write_bin_log(session, *session->getQueryString());
1059
table->print_error(error, MYF(0));
1063
table::Cache::singleton().mutex().unlock();
1064
table_list->table= NULL;
955
if (error == HA_ERR_WRONG_COMMAND)
958
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
959
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
965
write_bin_log(session, session->query, session->query_length);
970
table->print_error(error, MYF(0));
975
session->unlink_open_table(name_lock);
977
pthread_mutex_unlock(&LOCK_open);
978
table_list->table= NULL;
1070
982
/* We have to do full alter table. */
1071
new_engine= create_info->db_type;
1073
if (mysql_prepare_alter_table(session, table, create_info, original_proto, create_proto, alter_info))
1078
set_table_default_charset(create_info, new_table_identifier.getSchemaName().c_str());
983
new_db_type= create_info->db_type;
985
if (mysql_prepare_alter_table(session, table, create_info, create_proto,
989
set_table_default_charset(create_info, db);
1080
991
alter_info->build_method= HA_BUILD_OFFLINE;
1082
993
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
995
/* Safety fix for innodb */
996
my_casedn_str(files_charset_info, tmp_name);
1084
998
/* Create a temporary table with the new format */
1086
@note we make an internal temporary table unless the table is a temporary table. In last
1087
case we just use it as is. Neither of these tables require locks in order to be
1090
TableIdentifier new_table_as_temporary(original_table_identifier.getSchemaName(),
1092
create_proto.type() != message::Table::TEMPORARY ? message::Table::INTERNAL :
1093
message::Table::TEMPORARY);
1095
error= create_temporary_table(session, new_table_as_temporary, create_info, create_proto, alter_info);
1001
@note we make an internal temporary table unless the table is a temporary table. In last
1002
case we just use it as is. Neither of these tables require locks in order to be
1005
TableIdentifier new_table_temp(new_db,
1007
create_proto->type() != message::Table::TEMPORARY ? INTERNAL_TMP_TABLE :
1010
error= create_temporary_table(session, table, new_table_temp, create_info, create_proto, alter_info);
1102
1016
/* 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);
1108
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1017
new_table= open_alter_table(session, table, new_db, tmp_name);
1019
if (new_table == NULL)
1112
1022
/* 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
1116
session->cuted_fields= 0L;
1117
session->set_proc_info("copy to tmp table");
1120
/* We don't want update TIMESTAMP fields during ALTER Table. */
1121
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1122
new_table->next_number_field= new_table->found_next_number_field;
1123
error= copy_data_between_tables(session,
1126
alter_info->create_list,
1132
alter_info->keys_onoff,
1133
alter_info->error_if_not_empty);
1135
/* We must not ignore bad input! */
1136
assert(session->count_cuted_fields == CHECK_FIELD_ERROR_FOR_NULL);
1139
/* Now we need to resolve what just happened with the data copy. */
1145
No default value was provided for a DATE/DATETIME field, the
1146
current sql_mode doesn't allow the '0000-00-00' value and
1147
the table to be altered isn't empty.
1150
if (alter_info->error_if_not_empty && session->row_count)
1152
my_error(ER_INVALID_ALTER_TABLE_FOR_NOT_NULL, MYF(0));
1155
if (original_table_identifier.isTmp())
1159
/* close_temporary_table() frees the new_table pointer. */
1160
session->close_temporary_table(new_table);
1164
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1174
Close the intermediate table that will be the new table.
1175
Note that MERGE tables do not have their children attached here.
1177
new_table->intern_close_table();
1178
if (new_table->hasShare())
1180
delete new_table->getMutableShare();
1186
table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
1188
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1189
table::Cache::singleton().mutex().unlock();
1194
// Temporary table and success
1195
else if (original_table_identifier.isTmp())
1023
session->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
1024
session->cuted_fields= 0L;
1025
session->set_proc_info("copy to tmp table");
1030
/* We don't want update TIMESTAMP fields during ALTER Table. */
1031
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1032
new_table->next_number_field= new_table->found_next_number_field;
1033
error= copy_data_between_tables(table,
1035
alter_info->create_list,
1041
alter_info->keys_onoff,
1042
alter_info->error_if_not_empty);
1044
/* We must not ignore bad input! */
1045
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1047
if (table->s->tmp_table != NO_TMP_TABLE)
1049
/* We changed a temporary table */
1197
1053
/* Close lock if this is a transactional table */
1198
1054
if (session->lock)
1200
session->unlockTables(session->lock);
1056
mysql_unlock_tables(session, session->lock);
1201
1057
session->lock= 0;
1205
1061
session->close_temporary_table(table);
1207
1063
/* Should pass the 'new_name' as we store table name in the cache */
1208
new_table->getMutableShare()->setIdentifier(new_table_identifier);
1210
new_table_identifier.setPath(new_table_as_temporary.getPath());
1212
if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1217
// Normal table success
1064
if (new_table->rename_temporary_table(new_db, new_name))
1073
Close the intermediate table that will be the new table.
1074
Note that MERGE tables do not have their children attached here.
1076
new_table->intern_close_table();
1080
pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1084
TableIdentifier identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1085
quick_rm_table(*session, identifier);
1086
pthread_mutex_unlock(&LOCK_open);
1091
Data is copied. Now we:
1092
1) Wait until all other threads close old version of table.
1093
2) Close instances of table open by this thread and replace them
1094
with exclusive name-locks.
1095
3) Rename the old table to a temp name, rename the new one to the
1097
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1098
we reopen new version of table.
1099
5) Write statement to the binary log.
1100
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1101
remove name-locks from list of open tables and table cache.
1102
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1103
call to remove name-locks from table cache and list of open table.
1106
session->set_proc_info("rename result table");
1108
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1110
my_casedn_str(files_charset_info, old_name);
1112
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1113
session->close_data_files_and_morph_locks(db, table_name);
1116
save_old_db_type= old_db_type;
1119
This leads to the storage engine (SE) not being notified for renames in
1120
mysql_rename_table(), because we just juggle with the FRM and nothing
1121
more. If we have an intermediate table, then we notify the SE that
1122
it should become the actual table. Later, we will recycle the old table.
1123
However, in case of ALTER Table RENAME there might be no intermediate
1124
table. This is when the old and new tables are compatible, according to
1125
compare_table(). Then, we need one additional call to
1127
if (mysql_rename_table(old_db_type, db, table_name, db, old_name, FN_TO_IS_TMP))
1130
TableIdentifier identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1131
quick_rm_table(*session, identifier);
1223
Close the intermediate table that will be the new table.
1224
Note that MERGE tables do not have their children attached here.
1226
new_table->intern_close_table();
1228
if (new_table->hasShare())
1230
delete new_table->getMutableShare();
1236
table::Cache::singleton().mutex().lock(); /* ALTER TABLE */
1239
Data is copied. Now we:
1240
1) Wait until all other threads close old version of table.
1241
2) Close instances of table open by this thread and replace them
1242
with exclusive name-locks.
1243
3) Rename the old table to a temp name, rename the new one to the
1245
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1246
we reopen new version of table.
1247
5) Write statement to the binary log.
1248
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1249
remove name-locks from list of open tables and table cache.
1250
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1251
call to remove name-locks from table cache and list of open table.
1254
session->set_proc_info("rename result table");
1256
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1258
my_casedn_str(files_charset_info, old_name);
1260
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1261
session->close_data_files_and_morph_locks(original_table_identifier);
1266
This leads to the storage engine (SE) not being notified for renames in
1267
mysql_rename_table(), because we just juggle with the FRM and nothing
1268
more. If we have an intermediate table, then we notify the SE that
1269
it should become the actual table. Later, we will recycle the old table.
1270
However, in case of ALTER Table RENAME there might be no intermediate
1271
table. This is when the old and new tables are compatible, according to
1272
compare_table(). Then, we need one additional call to
1274
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);
1278
if (mysql_rename_table(*session, original_engine, original_table_identifier, original_table_to_drop))
1135
if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db, new_alias, FN_FROM_IS_TMP) != 0)
1137
/* Try to get everything back. */
1281
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1285
if (mysql_rename_table(*session, new_engine, new_table_as_temporary, new_table_identifier) != 0)
1287
/* Try to get everything back. */
1290
plugin::StorageEngine::dropTable(*session, new_table_identifier);
1292
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1294
mysql_rename_table(*session, original_engine, original_table_to_drop, original_table_identifier);
1298
plugin::StorageEngine::dropTable(*session, original_table_to_drop);
1305
An error happened while we were holding exclusive name-lock on table
1306
being altered. To be safe under LOCK TABLES we should remove placeholders
1307
from list of open tables list and table cache.
1309
session->unlink_open_table(table);
1310
table::Cache::singleton().mutex().unlock();
1315
table::Cache::singleton().mutex().unlock();
1317
session->set_proc_info("end");
1319
write_bin_log(session, *session->getQueryString());
1320
table_list->table= NULL;
1140
TableIdentifier alias_identifier(new_db, new_alias, NO_TMP_TABLE);
1141
quick_rm_table(*session, alias_identifier);
1143
TableIdentifier tmp_identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1144
quick_rm_table(*session, tmp_identifier);
1146
mysql_rename_table(old_db_type, db, old_name, db, table_name, FN_FROM_IS_TMP);
1152
/* This shouldn't happen. But let us play it safe. */
1153
goto err_with_placeholders;
1157
TableIdentifier old_identifier(db, old_name, INTERNAL_TMP_TABLE);
1158
quick_rm_table(*session, old_identifier);
1162
pthread_mutex_unlock(&LOCK_open);
1164
session->set_proc_info("end");
1166
write_bin_log(session, session->query, session->query_length);
1167
table_list->table= NULL;
1324
1171
* Field::store() may have called my_error(). If this is
1325
1172
* the case, we must not send an ok packet, since
1326
1173
* Diagnostics_area::is_set() will fail an assert.
1328
if (session->is_error())
1175
if (! session->is_error())
1177
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
1178
(ulong) (copied + deleted), (ulong) deleted,
1179
(ulong) session->cuted_fields);
1180
session->my_ok(copied + deleted, 0, 0L, tmp_name);
1181
session->some_tables_deleted=0;
1330
1186
/* my_error() was called. Return true (which means error...) */
1334
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
1335
(ulong) (copied + deleted), (ulong) deleted,
1336
(ulong) session->cuted_fields);
1337
session->my_ok(copied + deleted, 0, 0L, tmp_name);
1338
session->some_tables_deleted= 0;
1343
bool alter_table(Session *session,
1344
TableIdentifier &original_table_identifier,
1345
TableIdentifier &new_table_identifier,
1346
HA_CREATE_INFO *create_info,
1347
const message::Table &original_proto,
1348
message::Table &create_proto,
1349
TableList *table_list,
1350
AlterInfo *alter_info,
1358
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
1360
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
1361
return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
1364
session->set_proc_info("init");
1366
if (not (table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
1369
session->set_proc_info("gained write lock on table");
1372
Check that we are not trying to rename to an existing table,
1373
if one existed we get a lock, if we can't we error.
1376
Table *name_lock= NULL;
1378
if (not lockTableIfDifferent(*session, original_table_identifier, new_table_identifier, name_lock))
1383
error= internal_alter_table(session,
1385
original_table_identifier,
1386
new_table_identifier,
1398
table::Cache::singleton().mutex().lock(); /* ALTER TABLe */
1399
session->unlink_open_table(name_lock);
1400
table::Cache::singleton().mutex().unlock();
1193
/* close_temporary_table() frees the new_table pointer. */
1194
session->close_temporary_table(new_table);
1198
TableIdentifier tmp_identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1199
quick_rm_table(*session, tmp_identifier);
1204
No default value was provided for a DATE/DATETIME field, the
1205
current sql_mode doesn't allow the '0000-00-00' value and
1206
the table to be altered isn't empty.
1209
if (alter_info->error_if_not_empty && session->row_count)
1211
const char *f_val= 0;
1212
enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1213
switch (alter_info->datetime_field->sql_type)
1215
case DRIZZLE_TYPE_DATE:
1216
f_val= "0000-00-00";
1217
t_type= DRIZZLE_TIMESTAMP_DATE;
1219
case DRIZZLE_TYPE_DATETIME:
1220
f_val= "0000-00-00 00:00:00";
1221
t_type= DRIZZLE_TIMESTAMP_DATETIME;
1224
/* Shouldn't get here. */
1227
bool save_abort_on_warning= session->abort_on_warning;
1228
session->abort_on_warning= true;
1229
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1230
f_val, internal::strlength(f_val), t_type,
1231
alter_info->datetime_field->field_name);
1232
session->abort_on_warning= save_abort_on_warning;
1236
pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
1237
session->unlink_open_table(name_lock);
1238
pthread_mutex_unlock(&LOCK_open);
1242
err_with_placeholders:
1244
An error happened while we were holding exclusive name-lock on table
1245
being altered. To be safe under LOCK TABLES we should remove placeholders
1246
from list of open tables list and table cache.
1248
session->unlink_open_table(table);
1250
session->unlink_open_table(name_lock);
1251
pthread_mutex_unlock(&LOCK_open);
1406
1254
/* alter_table */
1409
copy_data_between_tables(Session *session,
1410
Table *from, Table *to,
1257
copy_data_between_tables(Table *from, Table *to,
1411
1258
List<CreateField> &create,
1413
uint32_t order_num, Order *order,
1260
uint32_t order_num, order_st *order,
1414
1261
ha_rows *copied,
1415
1262
ha_rows *deleted,
1416
1263
enum enum_enable_or_disable keys_onoff,