Loading mysql-test/r/type_timestamp.result +51 −9 Original line number Diff line number Diff line Loading @@ -122,40 +122,41 @@ t2 t4 t6 t8 t10 t12 t14 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 drop table t1; set new=0; create table t1 (t1 timestamp default '2003-01-01 00:00:00', t2 timestamp default '2003-01-01 00:00:00'); set TIMESTAMP=1000000000; insert into t1 values(); select * from t1; t1 t2 2001-09-09 04:46:40 2003-01-01 00:00:00 20010909044640 20030101000000 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `t1` timestamp(14) NOT NULL, `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00' `t2` timestamp(14) NOT NULL default '20030101000000' ) TYPE=MyISAM show columns from t1; Field Type Null Key Default Extra t1 timestamp(14) YES NULL t2 timestamp(14) YES 2003-01-01 00:00:00 t2 timestamp(14) YES 20030101000000 show columns from t1 like 't2'; Field Type Null Key Default Extra t2 timestamp(14) YES 2003-01-01 00:00:00 t2 timestamp(14) YES 20030101000000 create table t2 (select * from t1); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( `t1` timestamp(14) NOT NULL, `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00' `t2` timestamp(14) NOT NULL default '20030101000000' ) TYPE=MyISAM alter table t1 add column t0 timestamp first; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `t0` timestamp(14) NOT NULL, `t1` timestamp(14) NOT NULL default '2003-01-01 00:00:00', `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00' `t1` timestamp(14) NOT NULL default '20030101000000', `t2` timestamp(14) NOT NULL default '20030101000000' ) TYPE=MyISAM drop table t1,t2; create table t1 (ts1 timestamp, ts2 timestamp); Loading @@ -164,8 +165,8 @@ insert into t1 values (); insert into t1 values (DEFAULT, DEFAULT); select * from t1; ts1 ts2 2001-09-09 04:46:40 0000-00-00 00:00:00 2001-09-09 04:46:40 0000-00-00 00:00:00 20010909044640 00000000000000 20010909044640 00000000000000 drop table t1; create table t1 (ts timestamp(19)); show create table t1; Loading @@ -179,3 +180,44 @@ select * from t1; ts 2001-09-09 04:46:40 drop table t1; set new=1; create table t1 (a char(2), t timestamp); insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00'), ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; max(t) 2004-01-01 01:00:00 2004-02-01 00:00:00 drop table t1; create table t1 (ts1 timestamp); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `ts1` timestamp(19) NOT NULL ) TYPE=MyISAM alter table t1 add ts2 timestamp; set new=0; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `ts1` timestamp(19) NOT NULL, `ts2` timestamp(19) NOT NULL default '0000-00-00 00:00:00' ) TYPE=MyISAM drop table t1; create table t1 (ts1 timestamp); insert into t1 values ('2004-01-01 00:00:00'), ('2004-01-01 01:00:00'); select * from t1; ts1 20040101000000 20040101010000 set new=1; select * from t1; ts1 2004-01-01 00:00:00 2004-01-01 01:00:00 set new=0; select * from t1; ts1 20040101000000 20040101010000 drop table t1; mysql-test/t/type_timestamp.test +32 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ select * from t1; set new=1; select * from t1; drop table t1; set new=0; # # Bug #1885, bug #2539. Loading Loading @@ -116,3 +117,34 @@ set TIMESTAMP=1000000000; insert into t1 values (); select * from t1; drop table t1; # # Test for bug #4131, TIMESTAMP columns missing minutes and seconds when # using GROUP BY in @@new=1 mode. # set new=1; create table t1 (a char(2), t timestamp); insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00'), ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; drop table t1; # # More --new mode tests # Both columns created before and during alter should have same length. # create table t1 (ts1 timestamp); show create table t1; alter table t1 add ts2 timestamp; set new=0; show create table t1; drop table t1; # Selecting from table in --new mode should not affect further selects. create table t1 (ts1 timestamp); insert into t1 values ('2004-01-01 00:00:00'), ('2004-01-01 01:00:00'); select * from t1; set new=1; select * from t1; set new=0; select * from t1; drop table t1; sql/field.cc +5 −19 Original line number Diff line number Diff line Loading @@ -2467,8 +2467,7 @@ void Field_double::sql_type(String &res) const enum Item_result Field_timestamp::result_type() const { return (!current_thd->variables.new_mode && (field_length == 8 || field_length == 14) ? INT_RESULT : return ((field_length == 8 || field_length == 14) ? INT_RESULT : STRING_RESULT); } Loading @@ -2480,6 +2479,9 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, :Field_num(ptr_arg, len_arg, (uchar*) 0,0, unireg_check_arg, field_name_arg, table_arg, 0, 1, 1) #if MYSQL_VERSION_ID < 40100 , orig_field_length(len_arg) #endif { if (table && !table->timestamp_field) { Loading Loading @@ -2697,7 +2699,7 @@ String *Field_timestamp::val_str(String *val_buffer, time_t time_arg; struct tm *l_time; struct tm tm_tmp; my_bool new_format= (current_thd->variables.new_mode) || field_length == 19, my_bool new_format= field_length == 19, full_year=(field_length == 8 || field_length == 14 || new_format); int real_field_length= new_format ? 19 : field_length; Loading Loading @@ -2859,22 +2861,6 @@ void Field_timestamp::set_time() longstore(ptr,tmp); } /* This is an exact copy of Field_num except that 'length' is depending on --new mode */ void Field_timestamp::make_field(Send_field *field) { field->table_name=table_name; field->col_name=field_name; /* If --new, then we are using "YYYY-MM-DD HH:MM:SS" format */ field->length= current_thd->variables.new_mode ? 19 : field_length; field->type=type(); field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; field->decimals=dec; } /**************************************************************************** ** time type Loading sql/field.h +12 −1 Original line number Diff line number Diff line Loading @@ -546,6 +546,13 @@ class Field_null :public Field_str { class Field_timestamp :public Field_num { #if MYSQL_VERSION_ID < 40100 /* We save the original field length here because field_length is changed to a mock value in case when the 'new_mode' is in effect. */ uint32 orig_field_length; #endif public: Field_timestamp(char *ptr_arg, uint32 len_arg, enum utype unireg_check_arg, const char *field_name_arg, Loading Loading @@ -587,7 +594,11 @@ class Field_timestamp :public Field_num { void fill_and_store(char *from,uint len); bool get_date(TIME *ltime,bool fuzzydate); bool get_time(TIME *ltime); void make_field(Send_field *field); #if MYSQL_VERSION_ID < 40100 friend TABLE *open_table(THD *thd,const char *db,const char *table_name, const char *alias,bool *refresh); #endif }; Loading sql/sql_base.cc +25 −0 Original line number Diff line number Diff line Loading @@ -941,6 +941,31 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, for (uint i=0 ; i < table->fields ; i++) table->field[i]->table_name=table->table_name; } #if MYSQL_VERSION_ID < 40100 /* If per-connection "new" variable (represented by variables.new_mode) is set then we should pretend that the length of TIMESTAMP field is 19. The cheapest (from perfomance viewpoint) way to achieve that is to set field_length of all Field_timestamp objects in a table after opening it (to 19 if new_mode is true or to original field length otherwise). We save value of new_mode variable in TABLE::timestamp_mode to not perform this setup if new_mode value is the same between sequential table opens. */ my_bool new_mode= thd->variables.new_mode; if (table->timestamp_mode != new_mode) { for (uint i=0 ; i < table->fields ; i++) { Field *field= table->field[i]; if (field->type() == FIELD_TYPE_TIMESTAMP) field->field_length= new_mode ? 19 : ((Field_timestamp *)(field))->orig_field_length; } table->timestamp_mode= new_mode; } #endif /* These variables are also set in reopen_table() */ table->tablenr=thd->current_tablenr++; table->used_fields=0; Loading Loading
mysql-test/r/type_timestamp.result +51 −9 Original line number Diff line number Diff line Loading @@ -122,40 +122,41 @@ t2 t4 t6 t8 t10 t12 t14 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 drop table t1; set new=0; create table t1 (t1 timestamp default '2003-01-01 00:00:00', t2 timestamp default '2003-01-01 00:00:00'); set TIMESTAMP=1000000000; insert into t1 values(); select * from t1; t1 t2 2001-09-09 04:46:40 2003-01-01 00:00:00 20010909044640 20030101000000 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `t1` timestamp(14) NOT NULL, `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00' `t2` timestamp(14) NOT NULL default '20030101000000' ) TYPE=MyISAM show columns from t1; Field Type Null Key Default Extra t1 timestamp(14) YES NULL t2 timestamp(14) YES 2003-01-01 00:00:00 t2 timestamp(14) YES 20030101000000 show columns from t1 like 't2'; Field Type Null Key Default Extra t2 timestamp(14) YES 2003-01-01 00:00:00 t2 timestamp(14) YES 20030101000000 create table t2 (select * from t1); show create table t2; Table Create Table t2 CREATE TABLE `t2` ( `t1` timestamp(14) NOT NULL, `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00' `t2` timestamp(14) NOT NULL default '20030101000000' ) TYPE=MyISAM alter table t1 add column t0 timestamp first; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `t0` timestamp(14) NOT NULL, `t1` timestamp(14) NOT NULL default '2003-01-01 00:00:00', `t2` timestamp(14) NOT NULL default '2003-01-01 00:00:00' `t1` timestamp(14) NOT NULL default '20030101000000', `t2` timestamp(14) NOT NULL default '20030101000000' ) TYPE=MyISAM drop table t1,t2; create table t1 (ts1 timestamp, ts2 timestamp); Loading @@ -164,8 +165,8 @@ insert into t1 values (); insert into t1 values (DEFAULT, DEFAULT); select * from t1; ts1 ts2 2001-09-09 04:46:40 0000-00-00 00:00:00 2001-09-09 04:46:40 0000-00-00 00:00:00 20010909044640 00000000000000 20010909044640 00000000000000 drop table t1; create table t1 (ts timestamp(19)); show create table t1; Loading @@ -179,3 +180,44 @@ select * from t1; ts 2001-09-09 04:46:40 drop table t1; set new=1; create table t1 (a char(2), t timestamp); insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00'), ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; max(t) 2004-01-01 01:00:00 2004-02-01 00:00:00 drop table t1; create table t1 (ts1 timestamp); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `ts1` timestamp(19) NOT NULL ) TYPE=MyISAM alter table t1 add ts2 timestamp; set new=0; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `ts1` timestamp(19) NOT NULL, `ts2` timestamp(19) NOT NULL default '0000-00-00 00:00:00' ) TYPE=MyISAM drop table t1; create table t1 (ts1 timestamp); insert into t1 values ('2004-01-01 00:00:00'), ('2004-01-01 01:00:00'); select * from t1; ts1 20040101000000 20040101010000 set new=1; select * from t1; ts1 2004-01-01 00:00:00 2004-01-01 01:00:00 set new=0; select * from t1; ts1 20040101000000 20040101010000 drop table t1;
mysql-test/t/type_timestamp.test +32 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ select * from t1; set new=1; select * from t1; drop table t1; set new=0; # # Bug #1885, bug #2539. Loading Loading @@ -116,3 +117,34 @@ set TIMESTAMP=1000000000; insert into t1 values (); select * from t1; drop table t1; # # Test for bug #4131, TIMESTAMP columns missing minutes and seconds when # using GROUP BY in @@new=1 mode. # set new=1; create table t1 (a char(2), t timestamp); insert into t1 values ('a', '2004-01-01 00:00:00'), ('a', '2004-01-01 01:00:00'), ('b', '2004-02-01 00:00:00'); select max(t) from t1 group by a; drop table t1; # # More --new mode tests # Both columns created before and during alter should have same length. # create table t1 (ts1 timestamp); show create table t1; alter table t1 add ts2 timestamp; set new=0; show create table t1; drop table t1; # Selecting from table in --new mode should not affect further selects. create table t1 (ts1 timestamp); insert into t1 values ('2004-01-01 00:00:00'), ('2004-01-01 01:00:00'); select * from t1; set new=1; select * from t1; set new=0; select * from t1; drop table t1;
sql/field.cc +5 −19 Original line number Diff line number Diff line Loading @@ -2467,8 +2467,7 @@ void Field_double::sql_type(String &res) const enum Item_result Field_timestamp::result_type() const { return (!current_thd->variables.new_mode && (field_length == 8 || field_length == 14) ? INT_RESULT : return ((field_length == 8 || field_length == 14) ? INT_RESULT : STRING_RESULT); } Loading @@ -2480,6 +2479,9 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, :Field_num(ptr_arg, len_arg, (uchar*) 0,0, unireg_check_arg, field_name_arg, table_arg, 0, 1, 1) #if MYSQL_VERSION_ID < 40100 , orig_field_length(len_arg) #endif { if (table && !table->timestamp_field) { Loading Loading @@ -2697,7 +2699,7 @@ String *Field_timestamp::val_str(String *val_buffer, time_t time_arg; struct tm *l_time; struct tm tm_tmp; my_bool new_format= (current_thd->variables.new_mode) || field_length == 19, my_bool new_format= field_length == 19, full_year=(field_length == 8 || field_length == 14 || new_format); int real_field_length= new_format ? 19 : field_length; Loading Loading @@ -2859,22 +2861,6 @@ void Field_timestamp::set_time() longstore(ptr,tmp); } /* This is an exact copy of Field_num except that 'length' is depending on --new mode */ void Field_timestamp::make_field(Send_field *field) { field->table_name=table_name; field->col_name=field_name; /* If --new, then we are using "YYYY-MM-DD HH:MM:SS" format */ field->length= current_thd->variables.new_mode ? 19 : field_length; field->type=type(); field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags; field->decimals=dec; } /**************************************************************************** ** time type Loading
sql/field.h +12 −1 Original line number Diff line number Diff line Loading @@ -546,6 +546,13 @@ class Field_null :public Field_str { class Field_timestamp :public Field_num { #if MYSQL_VERSION_ID < 40100 /* We save the original field length here because field_length is changed to a mock value in case when the 'new_mode' is in effect. */ uint32 orig_field_length; #endif public: Field_timestamp(char *ptr_arg, uint32 len_arg, enum utype unireg_check_arg, const char *field_name_arg, Loading Loading @@ -587,7 +594,11 @@ class Field_timestamp :public Field_num { void fill_and_store(char *from,uint len); bool get_date(TIME *ltime,bool fuzzydate); bool get_time(TIME *ltime); void make_field(Send_field *field); #if MYSQL_VERSION_ID < 40100 friend TABLE *open_table(THD *thd,const char *db,const char *table_name, const char *alias,bool *refresh); #endif }; Loading
sql/sql_base.cc +25 −0 Original line number Diff line number Diff line Loading @@ -941,6 +941,31 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name, for (uint i=0 ; i < table->fields ; i++) table->field[i]->table_name=table->table_name; } #if MYSQL_VERSION_ID < 40100 /* If per-connection "new" variable (represented by variables.new_mode) is set then we should pretend that the length of TIMESTAMP field is 19. The cheapest (from perfomance viewpoint) way to achieve that is to set field_length of all Field_timestamp objects in a table after opening it (to 19 if new_mode is true or to original field length otherwise). We save value of new_mode variable in TABLE::timestamp_mode to not perform this setup if new_mode value is the same between sequential table opens. */ my_bool new_mode= thd->variables.new_mode; if (table->timestamp_mode != new_mode) { for (uint i=0 ; i < table->fields ; i++) { Field *field= table->field[i]; if (field->type() == FIELD_TYPE_TIMESTAMP) field->field_length= new_mode ? 19 : ((Field_timestamp *)(field))->orig_field_length; } table->timestamp_mode= new_mode; } #endif /* These variables are also set in reopen_table() */ table->tablenr=thd->current_tablenr++; table->used_fields=0; Loading