diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index db6f9043ec4..81286cea227 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -427,6 +427,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, KEY *key_info,*key_info_buffer; KEY_PART_INFO *key_part_info; int auto_increment=0; + int timestamps= 0, timestamps_with_niladic= 0; handler *file; int field_no,dup_no; enum db_type new_db_type; @@ -621,8 +622,22 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, sql_field->pack_flag=f_settype((uint) sql_field->sql_type); break; case FIELD_TYPE_TIMESTAMP: - sql_field->unireg_check=Field::TIMESTAMP_FIELD; - /* fall through */ + /* We should replace old TIMESTAMP fields with their newer analogs */ + if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD) + { + if (!timestamps) + { + sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD; + ++timestamps_with_niladic; + } + else + sql_field->unireg_check= Field::NONE; + } + else if(sql_field->unireg_check != Field::NONE) + ++timestamps_with_niladic; + + ++timestamps; + /* fall-through */ default: sql_field->pack_flag=(FIELDFLAG_NUMBER | (sql_field->flags & UNSIGNED_FLAG ? 0 : @@ -640,6 +655,11 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, auto_increment++; pos+=sql_field->pack_length; } + if (timestamps_with_niladic > 1) + { + my_error(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,MYF(0)); + DBUG_RETURN(-1); + } if (auto_increment > 1) { my_error(ER_WRONG_AUTO_KEY,MYF(0)); @@ -2100,10 +2120,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; char index_file[FN_REFLEN], data_file[FN_REFLEN]; - bool use_timestamp=0; ha_rows copied,deleted; ulonglong next_insert_id; - uint save_time_stamp,db_create_options, used_fields; + uint db_create_options, used_fields; enum db_type old_db_type,new_db_type; DBUG_ENTER("mysql_alter_table"); @@ -2321,8 +2340,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (def) { // Field is changed def->field=field; - if (def->sql_type == FIELD_TYPE_TIMESTAMP) - use_timestamp=1; if (!def->after) { create_list.push_back(def); @@ -2332,9 +2349,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, else { // Use old field value create_list.push_back(def=new create_field(field,field)); - if (def->sql_type == FIELD_TYPE_TIMESTAMP) - use_timestamp=1; - alter_it.rewind(); // Change default if ALTER Alter_column *alter; while ((alter=alter_it++)) @@ -2587,9 +2601,13 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } - save_time_stamp=new_table->time_stamp; - if (use_timestamp) - new_table->time_stamp=0; + + /* + We don't want update TIMESTAMP fields during ALTER TABLE + and copy_data_between_tables uses only write_row() for new_table so + don't need to set up timestamp_on_update_now member. + */ + new_table->timestamp_default_now= 0; new_table->next_number_field=new_table->found_next_number_field; thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields thd->cuted_fields=0L; @@ -2602,7 +2620,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, order_num, order, &copied, &deleted); thd->last_insert_id=next_insert_id; // Needed for correct log thd->count_cuted_fields= CHECK_FIELD_IGNORE; - new_table->time_stamp=save_time_stamp; if (table->tmp_table) { |