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,
655
bool alter_table(Session *session,
658
HA_CREATE_INFO *create_info,
659
message::Table *create_proto,
660
TableList *table_list,
661
AlterInfo *alter_info,
667
Table *new_table= NULL;
668
Table *name_lock= NULL;
891
671
char tmp_name[80];
892
672
char old_name[32];
673
char new_name_buff[FN_REFLEN];
674
char new_alias_buff[FN_REFLEN];
677
const char *new_alias;
678
char path[FN_REFLEN];
893
679
ha_rows copied= 0;
894
680
ha_rows deleted= 0;
896
if (not original_table_identifier.isValid())
899
if (not new_table_identifier.isValid())
681
plugin::StorageEngine *old_db_type;
682
plugin::StorageEngine *new_db_type;
683
plugin::StorageEngine *save_old_db_type;
686
new_name_buff[0]= '\0';
688
if (table_list && table_list->schema_table)
690
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
902
694
session->set_proc_info("init");
697
Assign variables table_name, new_name, db, new_db, path
698
to simplify further comparisons: we want to see if it's a RENAME
699
later just by comparing the pointers, avoiding the need for strcmp.
701
table_name= table_list->table_name;
703
if (! new_db || ! my_strcasecmp(table_alias_charset, new_db, db))
706
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
708
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
709
return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
712
build_table_filename(path, sizeof(path), db, table_name, false);
715
oss << drizzle_data_home << "/" << db << "/" << table_name;
717
(void) unpack_filename(new_name_buff, oss.str().c_str());
720
If this is just a rename of a view, short cut to the
721
following scenario: 1) lock LOCK_open 2) do a RENAME
723
This is a copy-paste added to make sure
724
ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
725
as an independent branch in mysql_execute_command. The need
726
for a copy-paste arose because the main code flow of ALTER Table
727
... RENAME tries to use openTableLock, which does not work for views
728
(openTableLock was never modified to merge table lists of child tables
729
into the main table list, like open_tables does).
730
This code is wrong and will be removed, please do not copy.
733
if (!(table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
904
736
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())
738
/* Check that we are not trying to rename to an existing table */
741
strcpy(new_name_buff, new_name);
742
strcpy(new_alias_buff, new_name);
743
new_alias= new_alias_buff;
745
my_casedn_str(files_charset_info, new_name_buff);
746
new_alias= new_name; // Create lower case table name
747
my_casedn_str(files_charset_info, new_name);
750
! my_strcasecmp(table_alias_charset, new_name_buff, table_name))
753
Source and destination table names are equal: make later check
756
new_alias= new_name= table_name;
760
if (table->s->tmp_table != NO_TMP_TABLE)
762
if (session->find_temporary_table(new_db, new_name_buff))
764
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
770
if (session->lock_table_name_if_not_cached(new_db, new_name, &name_lock))
775
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
779
build_table_filename(new_name_buff, sizeof(new_name_buff), new_db, new_name_buff, false);
781
if (plugin::StorageEngine::getTableDefinition(*session, new_name_buff, new_db, new_name_buff, false) == EEXIST)
783
/* Table will be closed by Session::executeCommand() */
784
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
792
new_alias= table_name;
793
new_name= table_name;
796
old_db_type= table->s->db_type();
797
if (! create_info->db_type)
799
create_info->db_type= old_db_type;
802
if (table->s->tmp_table != NO_TMP_TABLE)
803
create_info->options|= HA_LEX_CREATE_TMP_TABLE;
805
if (check_engine(session, new_name, create_info))
808
new_db_type= create_info->db_type;
810
if (new_db_type != old_db_type &&
811
!table->cursor->can_switch_engines())
929
814
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))
818
if (create_info->row_type == ROW_TYPE_NOT_USED)
819
create_info->row_type= table->s->row_type;
821
if (old_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
822
new_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
938
new_table_identifier.getSQLPath(path);
939
my_error(ER_ILLEGAL_HA, MYF(0), path.c_str());
824
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
944
828
session->set_proc_info("setup");
947
831
* test if no other bits except ALTER_RENAME and ALTER_KEYS_ONOFF are set
834
tmp.reset(ALTER_RENAME);
835
tmp.reset(ALTER_KEYS_ONOFF);
836
tmp&= alter_info->flags;
838
! 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());
840
switch (alter_info->keys_onoff)
846
wait_while_table_is_used() ensures that table being altered is
847
opened only by this thread and that Table::TableShare::version
848
of Table object corresponding to this table is 0.
849
The latter guarantees that no DML statement will open this table
850
until ALTER Table finishes (i.e. until close_thread_tables())
851
while the fact that the table is still open gives us protection
852
from concurrent DDL statements.
854
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
855
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
856
pthread_mutex_unlock(&LOCK_open);
857
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
858
/* COND_refresh will be signaled in close_thread_tables() */
861
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
862
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
863
pthread_mutex_unlock(&LOCK_open);
864
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
865
/* COND_refresh will be signaled in close_thread_tables() */
873
if (error == HA_ERR_WRONG_COMMAND)
876
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
877
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
881
pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
883
Unlike to the above case close_cached_table() below will remove ALL
884
instances of Table from table cache (it will also remove table lock
885
held by this thread). So to make actual table renaming and writing
886
to binlog atomic we have to put them into the same critical section
887
protected by LOCK_open mutex. This also removes gap for races between
888
access() and mysql_rename_table() calls.
892
(new_name != table_name || new_db != db))
894
session->set_proc_info("rename");
896
Then do a 'simple' rename of the table. First we need to close all
897
instances of 'source' table.
899
session->close_cached_table(table);
901
Then, we want check once again that target table does not exist.
902
Actually the order of these two steps does not matter since
903
earlier we took name-lock on the target table, so we do them
904
in this particular order only to be consistent with 5.0, in which
905
we don't take this name-lock and where this order really matters.
906
TODO: Investigate if we need this access() check at all.
908
if (plugin::StorageEngine::getTableDefinition(*session, new_name, db, table_name, false) == EEXIST)
910
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
915
*fn_ext(new_name)= 0;
916
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;
921
if (error == HA_ERR_WRONG_COMMAND)
924
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
925
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
931
write_bin_log(session, session->query, session->query_length);
936
table->cursor->print_error(error, MYF(0));
941
session->unlink_open_table(name_lock);
943
pthread_mutex_unlock(&LOCK_open);
944
table_list->table= NULL;
1070
948
/* 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());
951
If the old table had partitions and we are doing ALTER Table ...
952
engine= <new_engine>, the new table must preserve the original
953
partitioning. That means that the new engine is still the
954
partitioning engine, not the engine specified in the parser.
955
This is discovered in prep_alter_part_table, which in such case
956
updates create_info->db_type.
957
Now we need to update the stack copy of create_info->db_type,
958
as otherwise we won't be able to correctly move the files of the
959
temporary table to the result table files.
961
new_db_type= create_info->db_type;
963
if (mysql_prepare_alter_table(session, table, create_info, create_proto,
967
set_table_default_charset(create_info, db);
1080
969
alter_info->build_method= HA_BUILD_OFFLINE;
1082
971
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
973
/* Safety fix for innodb */
974
my_casedn_str(files_charset_info, tmp_name);
1084
976
/* 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);
977
error= create_temporary_table(session, table, new_db, tmp_name, create_info, create_proto, alter_info);
1102
981
/* 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);
982
if (table->s->tmp_table)
987
tbl.table_name= tmp_name;
989
/* Table is in session->temporary_tables */
990
new_table= session->openTable(&tbl, (bool*) 0, DRIZZLE_LOCK_IGNORE_FLUSH);
994
char tmp_path[FN_REFLEN];
995
/* table is a normal table: Create temporary table in same directory */
996
build_table_filename(tmp_path, sizeof(tmp_path), new_db, tmp_name, true);
997
/* Open our intermediate table */
998
new_table= session->open_temporary_table(tmp_path, new_db, tmp_name, false);
1001
if (new_table == NULL)
1112
1004
/* 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())
1005
session->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
1006
session->cuted_fields= 0L;
1007
session->set_proc_info("copy to tmp table");
1012
/* We don't want update TIMESTAMP fields during ALTER Table. */
1013
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1014
new_table->next_number_field= new_table->found_next_number_field;
1015
error= copy_data_between_tables(table,
1017
alter_info->create_list,
1023
alter_info->keys_onoff,
1024
alter_info->error_if_not_empty);
1026
/* We must not ignore bad input! */
1027
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1029
if (table->s->tmp_table != NO_TMP_TABLE)
1031
/* We changed a temporary table */
1197
1035
/* Close lock if this is a transactional table */
1198
1036
if (session->lock)
1200
session->unlockTables(session->lock);
1038
mysql_unlock_tables(session, session->lock);
1201
1039
session->lock= 0;
1204
1042
/* Remove link to old table and rename the new one */
1205
session->close_temporary_table(table);
1043
session->close_temporary_table(table, true, true);
1207
1045
/* 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
1046
if (new_table->rename_temporary_table(new_db, new_name))
1055
Close the intermediate table that will be the new table.
1056
Note that MERGE tables do not have their children attached here.
1058
new_table->intern_close_table();
1062
pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1066
quick_rm_table(*session, new_db, tmp_name, true);
1067
pthread_mutex_unlock(&LOCK_open);
1072
Data is copied. Now we:
1073
1) Wait until all other threads close old version of table.
1074
2) Close instances of table open by this thread and replace them
1075
with exclusive name-locks.
1076
3) Rename the old table to a temp name, rename the new one to the
1078
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1079
we reopen new version of table.
1080
5) Write statement to the binary log.
1081
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1082
remove name-locks from list of open tables and table cache.
1083
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1084
call to remove name-locks from table cache and list of open table.
1087
session->set_proc_info("rename result table");
1089
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1091
my_casedn_str(files_charset_info, old_name);
1093
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1094
session->close_data_files_and_morph_locks(db, table_name);
1097
save_old_db_type= old_db_type;
1100
This leads to the storage engine (SE) not being notified for renames in
1101
mysql_rename_table(), because we just juggle with the FRM and nothing
1102
more. If we have an intermediate table, then we notify the SE that
1103
it should become the actual table. Later, we will recycle the old table.
1104
However, in case of ALTER Table RENAME there might be no intermediate
1105
table. This is when the old and new tables are compatible, according to
1106
compare_table(). Then, we need one additional call to
1107
mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
1108
actual rename in the SE and the FRM is not touched. Note that, if the
1109
table is renamed and the SE is also changed, then an intermediate table
1110
is created and the additional call will not take place.
1112
if (mysql_rename_table(old_db_type, db, table_name, db, old_name, FN_TO_IS_TMP))
1115
quick_rm_table(*session, new_db, tmp_name, true);
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))
1119
if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db, new_alias, FN_FROM_IS_TMP) != 0)
1121
/* Try to get everything back. */
1281
plugin::StorageEngine::dropTable(*session, new_table_as_temporary);
1123
quick_rm_table(*session, new_db, new_alias, false);
1124
quick_rm_table(*session, new_db, tmp_name, true);
1125
mysql_rename_table(old_db_type, db, old_name, db, table_name, FN_FROM_IS_TMP);
1131
/* This shouldn't happen. But let us play it safe. */
1132
goto err_with_placeholders;
1135
quick_rm_table(*session, db, old_name, true);
1137
pthread_mutex_unlock(&LOCK_open);
1139
session->set_proc_info("end");
1141
write_bin_log(session, session->query, session->query_length);
1143
if (old_db_type->check_flag(HTON_BIT_FLUSH_AFTER_RENAME))
1146
For the alter table to be properly flushed to the logs, we
1147
have to open the new table. If not, we get a problem on server
1148
shutdown. But we do not need to attach MERGE children.
1150
char table_path[FN_REFLEN];
1152
build_table_filename(table_path, sizeof(table_path), new_db, table_name, false);
1153
t_table= session->open_temporary_table(table_path, new_db, tmp_name, false);
1156
t_table->intern_close_table();
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;
1160
errmsg_printf(ERRMSG_LVL_WARN, _("Could not open table %s.%s after rename\n"), new_db, table_name);
1162
plugin::StorageEngine::flushLogs(old_db_type);
1164
table_list->table= NULL;
1324
1168
* Field::store() may have called my_error(). If this is
1325
1169
* the case, we must not send an ok packet, since
1326
1170
* Diagnostics_area::is_set() will fail an assert.
1328
if (session->is_error())
1172
if (! session->is_error())
1174
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
1175
(ulong) (copied + deleted), (ulong) deleted,
1176
(ulong) session->cuted_fields);
1177
session->my_ok(copied + deleted, 0, 0L, tmp_name);
1178
session->some_tables_deleted=0;
1330
1183
/* 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();
1190
/* close_temporary_table() frees the new_table pointer. */
1191
session->close_temporary_table(new_table, true, true);
1194
quick_rm_table(*session, new_db, tmp_name, true);
1198
No default value was provided for a DATE/DATETIME field, the
1199
current sql_mode doesn't allow the '0000-00-00' value and
1200
the table to be altered isn't empty.
1203
if (alter_info->error_if_not_empty && session->row_count)
1205
const char *f_val= 0;
1206
enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1207
switch (alter_info->datetime_field->sql_type)
1209
case DRIZZLE_TYPE_DATE:
1210
f_val= "0000-00-00";
1211
t_type= DRIZZLE_TIMESTAMP_DATE;
1213
case DRIZZLE_TYPE_DATETIME:
1214
f_val= "0000-00-00 00:00:00";
1215
t_type= DRIZZLE_TIMESTAMP_DATETIME;
1218
/* Shouldn't get here. */
1221
bool save_abort_on_warning= session->abort_on_warning;
1222
session->abort_on_warning= true;
1223
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1224
f_val, strlength(f_val), t_type,
1225
alter_info->datetime_field->field_name);
1226
session->abort_on_warning= save_abort_on_warning;
1230
pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
1231
session->unlink_open_table(name_lock);
1232
pthread_mutex_unlock(&LOCK_open);
1236
err_with_placeholders:
1238
An error happened while we were holding exclusive name-lock on table
1239
being altered. To be safe under LOCK TABLES we should remove placeholders
1240
from list of open tables list and table cache.
1242
session->unlink_open_table(table);
1244
session->unlink_open_table(name_lock);
1245
pthread_mutex_unlock(&LOCK_open);
1406
1248
/* alter_table */
1409
copy_data_between_tables(Session *session,
1410
Table *from, Table *to,
1411
List<CreateField> &create,
1251
copy_data_between_tables(Table *from,Table *to,
1252
List<CreateField> &create,
1413
uint32_t order_num, Order *order,
1254
uint32_t order_num, order_st *order,
1416
1257
enum enum_enable_or_disable keys_onoff,
1417
1258
bool error_if_not_empty)
1420
1261
CopyField *copy,*copy_end;
1421
1262
ulong found_count,delete_count;
1263
Session *session= current_session;
1422
1264
uint32_t length= 0;
1423
SortField *sortorder;
1265
SORT_FIELD *sortorder;
1425
1267
TableList tables;
1426
1268
List<Item> fields;
1427
1269
List<Item> all_fields;