684
bool alter_table(Session *session,
687
HA_CREATE_INFO *create_info,
688
message::Table &create_proto,
689
TableList *table_list,
690
AlterInfo *alter_info,
775
static bool internal_alter_table(Session *session,
777
TableIdentifier &original_table_identifier,
778
TableIdentifier &new_table_identifier,
779
HA_CREATE_INFO *create_info,
780
message::Table &create_proto,
781
TableList *table_list,
782
AlterInfo *alter_info,
696
787
Table *new_table= NULL;
697
Table *name_lock= NULL;
700
789
char tmp_name[80];
701
790
char old_name[32];
704
const char *new_alias;
705
791
ha_rows copied= 0;
706
792
ha_rows deleted= 0;
707
plugin::StorageEngine *old_db_type;
708
plugin::StorageEngine *new_db_type;
709
plugin::StorageEngine *save_old_db_type;
794
message::Table *original_table_definition= table->s->getTableProto();
712
796
session->set_proc_info("init");
715
Assign variables table_name, new_name, db, new_db, path
716
to simplify further comparisons: we want to see if it's a RENAME
717
later just by comparing the pointers, avoiding the need for strcmp.
719
table_name= table_list->table_name;
721
if (! new_db || ! my_strcasecmp(table_alias_charset, new_db, db))
724
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
726
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
727
return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
731
If this is just a rename of a view, short cut to the
732
following scenario: 1) lock LOCK_open 2) do a RENAME
734
This is a copy-paste added to make sure
735
ALTER (sic:) Table .. RENAME works for views. ALTER VIEW is handled
736
as an independent branch in mysql_execute_command. The need
737
for a copy-paste arose because the main code flow of ALTER Table
738
... RENAME tries to use openTableLock, which does not work for views
739
(openTableLock was never modified to merge table lists of child tables
740
into the main table list, like open_tables does).
741
This code is wrong and will be removed, please do not copy.
744
if (not (table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
747
798
table->use_all_columns();
749
/* Check that we are not trying to rename to an existing table */
752
char new_alias_buff[FN_REFLEN];
753
char lower_case_table_name[FN_REFLEN];
755
strcpy(lower_case_table_name, new_name);
756
strcpy(new_alias_buff, new_name);
757
new_alias= new_alias_buff;
759
my_casedn_str(files_charset_info, lower_case_table_name);
760
new_alias= new_name; // Create lower case table name
761
my_casedn_str(files_charset_info, new_name);
764
not my_strcasecmp(table_alias_charset, lower_case_table_name, table_name))
767
Source and destination table names are equal: make later check
770
new_alias= new_name= table_name;
774
if (table->s->tmp_table != STANDARD_TABLE)
776
if (session->find_temporary_table(new_db, lower_case_table_name))
778
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), lower_case_table_name);
784
if (session->lock_table_name_if_not_cached(new_db, new_name, &name_lock))
789
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
793
TableIdentifier identifier(new_db, lower_case_table_name);
795
if (plugin::StorageEngine::doesTableExist(*session, identifier))
797
/* Table will be closed by Session::executeCommand() */
798
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
806
new_alias= table_name;
807
new_name= table_name;
810
old_db_type= table->s->db_type();
800
plugin::StorageEngine *new_engine;
801
plugin::StorageEngine *original_engine;
803
original_engine= table->s->getEngine();
811
805
if (not create_info->db_type)
813
create_info->db_type= old_db_type;
807
create_info->db_type= original_engine;
816
create_proto.set_schema(new_db);
818
if (table->s->tmp_table != STANDARD_TABLE)
809
new_engine= create_info->db_type;
812
create_proto.set_schema(new_table_identifier.getSchemaName().c_str());
814
if (new_table_identifier.isTmp())
820
816
create_proto.set_type(message::Table::TEMPORARY);
844
847
table_options= create_proto.mutable_options();
846
849
create_info->row_type= table->s->row_type;
847
table_options->set_row_type((message::Table_TableOptions_RowType)table->s->row_type);
850
if (old_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED) ||
851
new_db_type->check_flag(HTON_BIT_ALTER_NOT_SUPPORTED))
853
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
850
table_options->set_row_type(original_table_definition->options().row_type());
857
853
session->set_proc_info("setup");
860
856
* test if no other bits except ALTER_RENAME and ALTER_KEYS_ONOFF are set
863
tmp.reset(ALTER_RENAME);
864
tmp.reset(ALTER_KEYS_ONOFF);
865
tmp&= alter_info->flags;
867
! table->s->tmp_table) // no need to touch frm
869
switch (alter_info->keys_onoff)
875
wait_while_table_is_used() ensures that table being altered is
876
opened only by this thread and that Table::TableShare::version
877
of Table object corresponding to this table is 0.
878
The latter guarantees that no DML statement will open this table
879
until ALTER Table finishes (i.e. until close_thread_tables())
880
while the fact that the table is still open gives us protection
881
from concurrent DDL statements.
883
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
884
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
885
pthread_mutex_unlock(&LOCK_open);
886
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
887
/* COND_refresh will be signaled in close_thread_tables() */
890
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
891
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
892
pthread_mutex_unlock(&LOCK_open);
893
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
894
/* COND_refresh will be signaled in close_thread_tables() */
902
if (error == HA_ERR_WRONG_COMMAND)
905
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
906
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
910
pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
912
Unlike to the above case close_cached_table() below will remove ALL
913
instances of Table from table cache (it will also remove table lock
914
held by this thread). So to make actual table renaming and writing
915
to binlog atomic we have to put them into the same critical section
916
protected by LOCK_open mutex. This also removes gap for races between
917
access() and mysql_rename_table() calls.
921
(new_name != table_name || new_db != db))
923
session->set_proc_info("rename");
925
Then do a 'simple' rename of the table. First we need to close all
926
instances of 'source' table.
928
session->close_cached_table(table);
930
Then, we want check once again that target table does not exist.
931
Actually the order of these two steps does not matter since
932
earlier we took name-lock on the target table, so we do them
933
in this particular order only to be consistent with 5.0, in which
934
we don't take this name-lock and where this order really matters.
935
TODO: Investigate if we need this access() check at all.
937
TableIdentifier identifier(db, table_name);
938
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
940
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
862
tmp.reset(ALTER_RENAME);
863
tmp.reset(ALTER_KEYS_ONOFF);
864
tmp&= alter_info->flags;
866
if (! (tmp.any()) && ! table->s->tmp_table) // no need to touch frm
868
switch (alter_info->keys_onoff)
874
wait_while_table_is_used() ensures that table being altered is
875
opened only by this thread and that Table::TableShare::version
876
of Table object corresponding to this table is 0.
877
The latter guarantees that no DML statement will open this table
878
until ALTER Table finishes (i.e. until close_thread_tables())
879
while the fact that the table is still open gives us protection
880
from concurrent DDL statements.
882
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
883
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
884
pthread_mutex_unlock(&LOCK_open);
885
error= table->cursor->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
886
/* COND_refresh will be signaled in close_thread_tables() */
889
pthread_mutex_lock(&LOCK_open); /* DDL wait for/blocker */
890
wait_while_table_is_used(session, table, HA_EXTRA_FORCE_REOPEN);
891
pthread_mutex_unlock(&LOCK_open);
892
error=table->cursor->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
893
/* COND_refresh will be signaled in close_thread_tables() */
901
if (error == HA_ERR_WRONG_COMMAND)
904
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
905
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
909
pthread_mutex_lock(&LOCK_open); /* Lock to remove all instances of table from table cache before ALTER */
911
Unlike to the above case close_cached_table() below will remove ALL
912
instances of Table from table cache (it will also remove table lock
913
held by this thread). So to make actual table renaming and writing
914
to binlog atomic we have to put them into the same critical section
915
protected by LOCK_open mutex. This also removes gap for races between
916
access() and mysql_rename_table() calls.
919
if (error == 0 && not (original_table_identifier == new_table_identifier))
921
session->set_proc_info("rename");
923
Then do a 'simple' rename of the table. First we need to close all
924
instances of 'source' table.
926
session->close_cached_table(table);
928
Then, we want check once again that target table does not exist.
929
Actually the order of these two steps does not matter since
930
earlier we took name-lock on the target table, so we do them
931
in this particular order only to be consistent with 5.0, in which
932
we don't take this name-lock and where this order really matters.
933
@todo Investigate if we need this access() check at all.
935
if (plugin::StorageEngine::doesTableExist(*session, new_table_identifier))
937
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_table_identifier.getSQLPath().c_str());
942
if (mysql_rename_table(original_engine, original_table_identifier, new_table_identifier, 0))
949
if (error == HA_ERR_WRONG_COMMAND)
952
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
953
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
959
write_bin_log(session, session->query.c_str());
964
table->print_error(error, MYF(0));
945
*internal::fn_ext(new_name)= 0;
946
if (mysql_rename_table(old_db_type, db, table_name, new_db, new_alias, 0))
951
if (error == HA_ERR_WRONG_COMMAND)
954
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
955
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
961
write_bin_log(session, session->query.c_str());
966
table->print_error(error, MYF(0));
971
session->unlink_open_table(name_lock);
973
pthread_mutex_unlock(&LOCK_open);
974
table_list->table= NULL;
968
pthread_mutex_unlock(&LOCK_open);
969
table_list->table= NULL;
978
975
/* We have to do full alter table. */
979
new_db_type= create_info->db_type;
976
new_engine= create_info->db_type;
981
978
if (mysql_prepare_alter_table(session, table, create_info, create_proto, alter_info))
984
set_table_default_charset(create_info, db);
983
set_table_default_charset(create_info, new_table_identifier.getSchemaName().c_str());
986
985
alter_info->build_method= HA_BUILD_OFFLINE;
988
987
snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
990
/* Safety fix for innodb */
991
my_casedn_str(files_charset_info, tmp_name);
993
989
/* Create a temporary table with the new format */
991
@note we make an internal temporary table unless the table is a temporary table. In last
992
case we just use it as is. Neither of these tables require locks in order to be
995
TableIdentifier new_table_as_temporary(original_table_identifier.getSchemaName(),
997
create_proto.type() != message::Table::TEMPORARY ? INTERNAL_TMP_TABLE :
1000
error= create_temporary_table(session, new_table_as_temporary, create_info, create_proto, alter_info);
996
@note we make an internal temporary table unless the table is a temporary table. In last
997
case we just use it as is. Neither of these tables require locks in order to be
1000
TableIdentifier new_table_temp(new_db,
1002
create_proto.type() != message::Table::TEMPORARY ? INTERNAL_TMP_TABLE :
1005
error= create_temporary_table(session, new_table_temp, create_info, create_proto, alter_info);
1011
1007
/* Open the table so we need to copy the data to it. */
1012
new_table= open_alter_table(session, table, new_db, tmp_name);
1008
new_table= open_alter_table(session, table, new_table_as_temporary);
1014
if (new_table == NULL)
1012
quick_rm_table(*session, new_table_as_temporary);
1017
1016
/* Copy the data if necessary. */
1018
session->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
1019
session->cuted_fields= 0L;
1020
session->set_proc_info("copy to tmp table");
1025
/* We don't want update TIMESTAMP fields during ALTER Table. */
1026
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1027
new_table->next_number_field= new_table->found_next_number_field;
1028
error= copy_data_between_tables(table,
1030
alter_info->create_list,
1036
alter_info->keys_onoff,
1037
alter_info->error_if_not_empty);
1039
/* We must not ignore bad input! */
1040
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1042
if (table->s->tmp_table != STANDARD_TABLE)
1044
/* We changed a temporary table */
1018
session->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
1019
session->cuted_fields= 0L;
1020
session->set_proc_info("copy to tmp table");
1023
/* We don't want update TIMESTAMP fields during ALTER Table. */
1024
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1025
new_table->next_number_field= new_table->found_next_number_field;
1026
error= copy_data_between_tables(table,
1028
alter_info->create_list,
1034
alter_info->keys_onoff,
1035
alter_info->error_if_not_empty);
1037
/* We must not ignore bad input! */
1038
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1041
/* Now we need to resolve what just happened with the data copy. */
1047
No default value was provided for a DATE/DATETIME field, the
1048
current sql_mode doesn't allow the '0000-00-00' value and
1049
the table to be altered isn't empty.
1052
if (alter_info->error_if_not_empty && session->row_count)
1054
const char *f_val= 0;
1055
enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1057
switch (alter_info->datetime_field->sql_type)
1059
case DRIZZLE_TYPE_DATE:
1060
f_val= "0000-00-00";
1061
t_type= DRIZZLE_TIMESTAMP_DATE;
1063
case DRIZZLE_TYPE_DATETIME:
1064
f_val= "0000-00-00 00:00:00";
1065
t_type= DRIZZLE_TIMESTAMP_DATETIME;
1068
/* Shouldn't get here. */
1071
bool save_abort_on_warning= session->abort_on_warning;
1072
session->abort_on_warning= true;
1073
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1074
f_val, internal::strlength(f_val), t_type,
1075
alter_info->datetime_field->field_name);
1076
session->abort_on_warning= save_abort_on_warning;
1079
if (original_table_identifier.isTmp())
1083
/* close_temporary_table() frees the new_table pointer. */
1084
session->close_temporary_table(new_table);
1088
quick_rm_table(*session, new_table_as_temporary);
1098
Close the intermediate table that will be the new table.
1099
Note that MERGE tables do not have their children attached here.
1101
new_table->intern_close_table();
1105
pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1107
quick_rm_table(*session, new_table_as_temporary);
1108
pthread_mutex_unlock(&LOCK_open);
1113
// Temporary table and success
1114
else if (original_table_identifier.isTmp())
1048
1116
/* Close lock if this is a transactional table */
1049
1117
if (session->lock)
1056
1124
session->close_temporary_table(table);
1058
1126
/* Should pass the 'new_name' as we store table name in the cache */
1059
if (new_table->rename_temporary_table(new_db, new_name))
1068
Close the intermediate table that will be the new table.
1069
Note that MERGE tables do not have their children attached here.
1071
new_table->intern_close_table();
1075
pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1079
TableIdentifier identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1080
quick_rm_table(*session, identifier);
1081
pthread_mutex_unlock(&LOCK_open);
1086
Data is copied. Now we:
1087
1) Wait until all other threads close old version of table.
1088
2) Close instances of table open by this thread and replace them
1089
with exclusive name-locks.
1090
3) Rename the old table to a temp name, rename the new one to the
1092
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1093
we reopen new version of table.
1094
5) Write statement to the binary log.
1095
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1096
remove name-locks from list of open tables and table cache.
1097
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1098
call to remove name-locks from table cache and list of open table.
1101
session->set_proc_info("rename result table");
1103
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1105
my_casedn_str(files_charset_info, old_name);
1107
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1108
session->close_data_files_and_morph_locks(db, table_name);
1111
save_old_db_type= old_db_type;
1114
This leads to the storage engine (SE) not being notified for renames in
1115
mysql_rename_table(), because we just juggle with the FRM and nothing
1116
more. If we have an intermediate table, then we notify the SE that
1117
it should become the actual table. Later, we will recycle the old table.
1118
However, in case of ALTER Table RENAME there might be no intermediate
1119
table. This is when the old and new tables are compatible, according to
1120
compare_table(). Then, we need one additional call to
1122
if (mysql_rename_table(old_db_type, db, table_name, db, old_name, FN_TO_IS_TMP))
1125
TableIdentifier identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1126
quick_rm_table(*session, identifier);
1127
if (new_table->renameAlterTemporaryTable(new_table_identifier))
1131
/* close_temporary_table() frees the new_table pointer. */
1132
session->close_temporary_table(new_table);
1136
quick_rm_table(*session, new_table_as_temporary);
1142
// Normal table success
1130
if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db, new_alias, FN_FROM_IS_TMP) != 0)
1132
/* Try to get everything back. */
1148
Close the intermediate table that will be the new table.
1149
Note that MERGE tables do not have their children attached here.
1151
new_table->intern_close_table();
1155
pthread_mutex_lock(&LOCK_open); /* ALTER TABLE */
1158
Data is copied. Now we:
1159
1) Wait until all other threads close old version of table.
1160
2) Close instances of table open by this thread and replace them
1161
with exclusive name-locks.
1162
3) Rename the old table to a temp name, rename the new one to the
1164
4) If we are under LOCK TABLES and don't do ALTER Table ... RENAME
1165
we reopen new version of table.
1166
5) Write statement to the binary log.
1167
6) If we are under LOCK TABLES and do ALTER Table ... RENAME we
1168
remove name-locks from list of open tables and table cache.
1169
7) If we are not not under LOCK TABLES we rely on close_thread_tables()
1170
call to remove name-locks from table cache and list of open table.
1173
session->set_proc_info("rename result table");
1175
snprintf(old_name, sizeof(old_name), "%s2-%lx-%"PRIx64, TMP_FILE_PREFIX, (unsigned long) current_pid, session->thread_id);
1177
my_casedn_str(files_charset_info, old_name);
1179
wait_while_table_is_used(session, table, HA_EXTRA_PREPARE_FOR_RENAME);
1180
session->close_data_files_and_morph_locks(original_table_identifier);
1185
This leads to the storage engine (SE) not being notified for renames in
1186
mysql_rename_table(), because we just juggle with the FRM and nothing
1187
more. If we have an intermediate table, then we notify the SE that
1188
it should become the actual table. Later, we will recycle the old table.
1189
However, in case of ALTER Table RENAME there might be no intermediate
1190
table. This is when the old and new tables are compatible, according to
1191
compare_table(). Then, we need one additional call to
1193
TableIdentifier original_table_to_drop(original_table_identifier.getSchemaName(),
1194
old_name, TEMP_TABLE);
1196
if (mysql_rename_table(original_engine, original_table_identifier, original_table_to_drop, FN_TO_IS_TMP))
1135
TableIdentifier alias_identifier(new_db, new_alias, STANDARD_TABLE);
1136
quick_rm_table(*session, alias_identifier);
1138
TableIdentifier tmp_identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1139
quick_rm_table(*session, tmp_identifier);
1141
mysql_rename_table(old_db_type, db, old_name, db, table_name, FN_FROM_IS_TMP);
1147
/* This shouldn't happen. But let us play it safe. */
1148
goto err_with_placeholders;
1152
TableIdentifier old_identifier(db, old_name, INTERNAL_TMP_TABLE);
1153
quick_rm_table(*session, old_identifier);
1157
pthread_mutex_unlock(&LOCK_open);
1159
session->set_proc_info("end");
1161
write_bin_log(session, session->query.c_str());
1162
table_list->table= NULL;
1199
quick_rm_table(*session, new_table_as_temporary);
1203
if (mysql_rename_table(new_engine, new_table_as_temporary, new_table_identifier, FN_FROM_IS_TMP) != 0)
1205
/* Try to get everything back. */
1208
quick_rm_table(*session, new_table_identifier);
1210
quick_rm_table(*session, new_table_as_temporary);
1212
mysql_rename_table(original_engine, original_table_to_drop, original_table_identifier, FN_FROM_IS_TMP);
1216
quick_rm_table(*session, original_table_to_drop);
1223
An error happened while we were holding exclusive name-lock on table
1224
being altered. To be safe under LOCK TABLES we should remove placeholders
1225
from list of open tables list and table cache.
1227
session->unlink_open_table(table);
1228
pthread_mutex_unlock(&LOCK_open);
1234
pthread_mutex_unlock(&LOCK_open);
1236
session->set_proc_info("end");
1238
write_bin_log(session, session->query.c_str());
1239
table_list->table= NULL;
1166
1243
* Field::store() may have called my_error(). If this is
1167
1244
* the case, we must not send an ok packet, since
1168
1245
* Diagnostics_area::is_set() will fail an assert.
1170
if (! session->is_error())
1172
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
1173
(ulong) (copied + deleted), (ulong) deleted,
1174
(ulong) session->cuted_fields);
1175
session->my_ok(copied + deleted, 0, 0L, tmp_name);
1176
session->some_tables_deleted=0;
1247
if (session->is_error())
1181
1249
/* my_error() was called. Return true (which means error...) */
1188
/* close_temporary_table() frees the new_table pointer. */
1189
session->close_temporary_table(new_table);
1193
TableIdentifier tmp_identifier(new_db, tmp_name, INTERNAL_TMP_TABLE);
1194
quick_rm_table(*session, tmp_identifier);
1199
No default value was provided for a DATE/DATETIME field, the
1200
current sql_mode doesn't allow the '0000-00-00' value and
1201
the table to be altered isn't empty.
1204
if (alter_info->error_if_not_empty && session->row_count)
1206
const char *f_val= 0;
1207
enum enum_drizzle_timestamp_type t_type= DRIZZLE_TIMESTAMP_DATE;
1208
switch (alter_info->datetime_field->sql_type)
1210
case DRIZZLE_TYPE_DATE:
1211
f_val= "0000-00-00";
1212
t_type= DRIZZLE_TIMESTAMP_DATE;
1214
case DRIZZLE_TYPE_DATETIME:
1215
f_val= "0000-00-00 00:00:00";
1216
t_type= DRIZZLE_TIMESTAMP_DATETIME;
1219
/* Shouldn't get here. */
1222
bool save_abort_on_warning= session->abort_on_warning;
1223
session->abort_on_warning= true;
1224
make_truncated_value_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1225
f_val, internal::strlength(f_val), t_type,
1226
alter_info->datetime_field->field_name);
1227
session->abort_on_warning= save_abort_on_warning;
1231
pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
1232
session->unlink_open_table(name_lock);
1233
pthread_mutex_unlock(&LOCK_open);
1237
err_with_placeholders:
1239
An error happened while we were holding exclusive name-lock on table
1240
being altered. To be safe under LOCK TABLES we should remove placeholders
1241
from list of open tables list and table cache.
1243
session->unlink_open_table(table);
1245
session->unlink_open_table(name_lock);
1246
pthread_mutex_unlock(&LOCK_open);
1253
snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
1254
(ulong) (copied + deleted), (ulong) deleted,
1255
(ulong) session->cuted_fields);
1256
session->my_ok(copied + deleted, 0, 0L, tmp_name);
1257
session->some_tables_deleted= 0;
1262
bool alter_table(Session *session,
1263
TableIdentifier &original_table_identifier,
1264
TableIdentifier &new_table_identifier,
1265
HA_CREATE_INFO *create_info,
1266
message::Table &create_proto,
1267
TableList *table_list,
1268
AlterInfo *alter_info,
1276
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
1278
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER Table */
1279
return mysql_discard_or_import_tablespace(session, table_list, alter_info->tablespace_op);
1282
session->set_proc_info("init");
1284
if (not (table= session->openTableLock(table_list, TL_WRITE_ALLOW_READ)))
1287
session->set_proc_info("gained write lock on table");
1290
Check that we are not trying to rename to an existing table,
1291
if one existed we get a lock, if we can't we error.
1294
Table *name_lock= NULL;
1296
if (not lockTableIfDifferent(*session, original_table_identifier, new_table_identifier, name_lock))
1301
error= internal_alter_table(session,
1303
original_table_identifier,
1304
new_table_identifier,
1315
pthread_mutex_lock(&LOCK_open); /* ALTER TABLe */
1316
session->unlink_open_table(name_lock);
1317
pthread_mutex_unlock(&LOCK_open);
1249
1323
/* alter_table */