Loading mysql-test/r/func_time.result +40 −0 Original line number Diff line number Diff line Loading @@ -720,3 +720,43 @@ Warning 1292 Truncated incorrect datetime value: '2005-01-00' select time_format('100:00:00', '%H %k %h %I %l'); time_format('100:00:00', '%H %k %h %I %l') 100 100 04 04 4 create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); create function t_slow_sysdate() returns timestamp begin do sleep(2); return sysdate(); end; // insert into t1 set a = sysdate(), b = t_slow_sysdate();// create trigger t_before before insert on t1 for each row begin set new.b = t_slow_sysdate(); end // insert into t1 set a = sysdate(); select a != b from t1; a != b 1 1 drop trigger t_before; drop function t_slow_sysdate; drop table t1; create table t1 (a datetime, i int, b datetime); insert into t1 select sysdate(), sleep(1), sysdate() from dual; select a != b from t1; a != b 1 drop table t1; create procedure t_sysdate() begin select sysdate() into @a; do sleep(2); select sysdate() into @b; select @a != @b; end; // call t_sysdate(); @a != @b 1 drop procedure t_sysdate; mysql-test/t/func_time.test +52 −0 Original line number Diff line number Diff line Loading @@ -353,3 +353,55 @@ select last_day('2005-01-00'); # the 0-11 range # select time_format('100:00:00', '%H %k %h %I %l'); # # Bug #12562: Make SYSDATE behave like it does in Oracle: always the current # time, regardless of magic to make NOW() always the same for the # entirety of a statement. create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); delimiter //; create function t_slow_sysdate() returns timestamp begin do sleep(2); return sysdate(); end; // insert into t1 set a = sysdate(), b = t_slow_sysdate();// create trigger t_before before insert on t1 for each row begin set new.b = t_slow_sysdate(); end // delimiter ;// insert into t1 set a = sysdate(); select a != b from t1; drop trigger t_before; drop function t_slow_sysdate; drop table t1; create table t1 (a datetime, i int, b datetime); insert into t1 select sysdate(), sleep(1), sysdate() from dual; select a != b from t1; drop table t1; delimiter //; create procedure t_sysdate() begin select sysdate() into @a; do sleep(2); select sysdate() into @b; select @a != @b; end; // delimiter ;// call t_sysdate(); drop procedure t_sysdate; # End of 5.0 tests sql/item_timefunc.cc +66 −2 Original line number Diff line number Diff line Loading @@ -1491,6 +1491,70 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions) } /* Converts current time in my_time_t to TIME represenatation for local time zone. Defines time zone (local) used for whole SYSDATE function. */ void Item_func_sysdate_local::store_now_in_TIME(TIME *now_time) { THD *thd= current_thd; thd->variables.time_zone->gmt_sec_to_TIME(now_time, time(NULL)); thd->time_zone_used= 1; } String *Item_func_sysdate_local::val_str(String *str) { DBUG_ASSERT(fixed == 1); store_now_in_TIME(<ime); buff_length= (uint) my_datetime_to_str(<ime, buff); str_value.set(buff, buff_length, &my_charset_bin); return &str_value; } longlong Item_func_sysdate_local::val_int() { DBUG_ASSERT(fixed == 1); store_now_in_TIME(<ime); return (longlong) TIME_to_ulonglong_datetime(<ime); } double Item_func_sysdate_local::val_real() { DBUG_ASSERT(fixed == 1); store_now_in_TIME(<ime); return (longlong) TIME_to_ulonglong_datetime(<ime); } void Item_func_sysdate_local::fix_length_and_dec() { decimals= 0; collation.set(&my_charset_bin); max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } bool Item_func_sysdate_local::get_date(TIME *res, uint fuzzy_date __attribute__((unused))) { store_now_in_TIME(<ime); *res= ltime; return 0; } int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions) { store_now_in_TIME(<ime); to->set_notnull(); to->store_time(<ime, MYSQL_TIMESTAMP_DATETIME); return 0; } String *Item_func_sec_to_time::val_str(String *str) { DBUG_ASSERT(fixed == 1); Loading sql/item_timefunc.h +27 −0 Original line number Diff line number Diff line Loading @@ -446,6 +446,7 @@ class Item_func_curdate_utc :public Item_func_curdate class Item_func_now :public Item_date_func { protected: longlong value; char buff[20*2+32]; // +32 to make my_snprintf_{8bit|ucs2} happy uint buff_length; Loading Loading @@ -485,6 +486,32 @@ class Item_func_now_utc :public Item_func_now }; /* This is like NOW(), but always uses the real current time, not the query_start(). This matches the Oracle behavior. */ class Item_func_sysdate_local :public Item_func_now { public: Item_func_sysdate_local() :Item_func_now() {} Item_func_sysdate_local(Item *a) :Item_func_now(a) {} bool const_item() const { return 0; } const char *func_name() const { return "sysdate"; } void store_now_in_TIME(TIME *now_time); double val_real(); longlong val_int(); int save_in_field(Field *to, bool no_conversions); String *val_str(String *str); void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); void update_used_tables() { Item_func_now::update_used_tables(); used_tables_cache|= RAND_TABLE_BIT; } }; class Item_func_from_days :public Item_date { public: Loading sql/lex.h +1 −1 Original line number Diff line number Diff line Loading @@ -751,7 +751,7 @@ static SYMBOL sql_functions[] = { { "SUBSTRING_INDEX", SYM(SUBSTRING_INDEX)}, { "SUBTIME", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_subtime)}, { "SUM", SYM(SUM_SYM)}, { "SYSDATE", SYM(NOW_SYM)}, { "SYSDATE", SYM(SYSDATE)}, { "SYSTEM_USER", SYM(USER)}, { "TAN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_tan)}, { "TIME_FORMAT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_time_format)}, Loading Loading
mysql-test/r/func_time.result +40 −0 Original line number Diff line number Diff line Loading @@ -720,3 +720,43 @@ Warning 1292 Truncated incorrect datetime value: '2005-01-00' select time_format('100:00:00', '%H %k %h %I %l'); time_format('100:00:00', '%H %k %h %I %l') 100 100 04 04 4 create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); create function t_slow_sysdate() returns timestamp begin do sleep(2); return sysdate(); end; // insert into t1 set a = sysdate(), b = t_slow_sysdate();// create trigger t_before before insert on t1 for each row begin set new.b = t_slow_sysdate(); end // insert into t1 set a = sysdate(); select a != b from t1; a != b 1 1 drop trigger t_before; drop function t_slow_sysdate; drop table t1; create table t1 (a datetime, i int, b datetime); insert into t1 select sysdate(), sleep(1), sysdate() from dual; select a != b from t1; a != b 1 drop table t1; create procedure t_sysdate() begin select sysdate() into @a; do sleep(2); select sysdate() into @b; select @a != @b; end; // call t_sysdate(); @a != @b 1 drop procedure t_sysdate;
mysql-test/t/func_time.test +52 −0 Original line number Diff line number Diff line Loading @@ -353,3 +353,55 @@ select last_day('2005-01-00'); # the 0-11 range # select time_format('100:00:00', '%H %k %h %I %l'); # # Bug #12562: Make SYSDATE behave like it does in Oracle: always the current # time, regardless of magic to make NOW() always the same for the # entirety of a statement. create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); delimiter //; create function t_slow_sysdate() returns timestamp begin do sleep(2); return sysdate(); end; // insert into t1 set a = sysdate(), b = t_slow_sysdate();// create trigger t_before before insert on t1 for each row begin set new.b = t_slow_sysdate(); end // delimiter ;// insert into t1 set a = sysdate(); select a != b from t1; drop trigger t_before; drop function t_slow_sysdate; drop table t1; create table t1 (a datetime, i int, b datetime); insert into t1 select sysdate(), sleep(1), sysdate() from dual; select a != b from t1; drop table t1; delimiter //; create procedure t_sysdate() begin select sysdate() into @a; do sleep(2); select sysdate() into @b; select @a != @b; end; // delimiter ;// call t_sysdate(); drop procedure t_sysdate; # End of 5.0 tests
sql/item_timefunc.cc +66 −2 Original line number Diff line number Diff line Loading @@ -1491,6 +1491,70 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions) } /* Converts current time in my_time_t to TIME represenatation for local time zone. Defines time zone (local) used for whole SYSDATE function. */ void Item_func_sysdate_local::store_now_in_TIME(TIME *now_time) { THD *thd= current_thd; thd->variables.time_zone->gmt_sec_to_TIME(now_time, time(NULL)); thd->time_zone_used= 1; } String *Item_func_sysdate_local::val_str(String *str) { DBUG_ASSERT(fixed == 1); store_now_in_TIME(<ime); buff_length= (uint) my_datetime_to_str(<ime, buff); str_value.set(buff, buff_length, &my_charset_bin); return &str_value; } longlong Item_func_sysdate_local::val_int() { DBUG_ASSERT(fixed == 1); store_now_in_TIME(<ime); return (longlong) TIME_to_ulonglong_datetime(<ime); } double Item_func_sysdate_local::val_real() { DBUG_ASSERT(fixed == 1); store_now_in_TIME(<ime); return (longlong) TIME_to_ulonglong_datetime(<ime); } void Item_func_sysdate_local::fix_length_and_dec() { decimals= 0; collation.set(&my_charset_bin); max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; } bool Item_func_sysdate_local::get_date(TIME *res, uint fuzzy_date __attribute__((unused))) { store_now_in_TIME(<ime); *res= ltime; return 0; } int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions) { store_now_in_TIME(<ime); to->set_notnull(); to->store_time(<ime, MYSQL_TIMESTAMP_DATETIME); return 0; } String *Item_func_sec_to_time::val_str(String *str) { DBUG_ASSERT(fixed == 1); Loading
sql/item_timefunc.h +27 −0 Original line number Diff line number Diff line Loading @@ -446,6 +446,7 @@ class Item_func_curdate_utc :public Item_func_curdate class Item_func_now :public Item_date_func { protected: longlong value; char buff[20*2+32]; // +32 to make my_snprintf_{8bit|ucs2} happy uint buff_length; Loading Loading @@ -485,6 +486,32 @@ class Item_func_now_utc :public Item_func_now }; /* This is like NOW(), but always uses the real current time, not the query_start(). This matches the Oracle behavior. */ class Item_func_sysdate_local :public Item_func_now { public: Item_func_sysdate_local() :Item_func_now() {} Item_func_sysdate_local(Item *a) :Item_func_now(a) {} bool const_item() const { return 0; } const char *func_name() const { return "sysdate"; } void store_now_in_TIME(TIME *now_time); double val_real(); longlong val_int(); int save_in_field(Field *to, bool no_conversions); String *val_str(String *str); void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); void update_used_tables() { Item_func_now::update_used_tables(); used_tables_cache|= RAND_TABLE_BIT; } }; class Item_func_from_days :public Item_date { public: Loading
sql/lex.h +1 −1 Original line number Diff line number Diff line Loading @@ -751,7 +751,7 @@ static SYMBOL sql_functions[] = { { "SUBSTRING_INDEX", SYM(SUBSTRING_INDEX)}, { "SUBTIME", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_subtime)}, { "SUM", SYM(SUM_SYM)}, { "SYSDATE", SYM(NOW_SYM)}, { "SYSDATE", SYM(SYSDATE)}, { "SYSTEM_USER", SYM(USER)}, { "TAN", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_tan)}, { "TIME_FORMAT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_time_format)}, Loading