List:Internals« Previous MessageNext Message »
From:Jim Winstead Date:August 18 2005 12:22am
Subject:bk commit into 5.0 tree (jimw:1.1988) BUG#12562
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of jimw. When jimw does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1988 05/08/17 17:22:44 jimw@stripped +6 -0
  Make SYSDATE() behave as in Oracle: always the current datetime, not the
  datetime of when the current statement began. This also makes SYSDATE()
  not safe in replication. (Bug #12562)

  sql/sql_yacc.yy
    1.415 05/08/17 17:22:41 jimw@stripped +5 -0
    Handle distinct SYSDATE symbol

  sql/lex.h
    1.140 05/08/17 17:22:41 jimw@stripped +1 -1
    Make distinct symbol for SYSDATE

  sql/item_timefunc.h
    1.58 05/08/17 17:22:41 jimw@stripped +14 -0
    Add Item_func_sysdate_local

  sql/item_timefunc.cc
    1.93 05/08/17 17:22:41 jimw@stripped +12 -0
    Add Item_func_sysdate_local::store_now_in_TIME()

  mysql-test/t/func_time.test
    1.37 05/08/17 17:22:41 jimw@stripped +34 -0
    Add regression test

  mysql-test/r/func_time.result
    1.45 05/08/17 17:22:41 jimw@stripped +22 -0
    Add results

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	jimw
# Host:	rama.(none)
# Root:	/home/jimw/my/mysql-5.0-12562

--- 1.92/sql/item_timefunc.cc	2005-08-02 15:28:05 -07:00
+++ 1.93/sql/item_timefunc.cc	2005-08-17 17:22:41 -07:00
@@ -1475,6 +1475,18 @@
 }
 
 
+/*
+    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;
+}
+
+
 bool Item_func_now::get_date(TIME *res,
 			     uint fuzzy_date __attribute__((unused)))
 {

--- 1.57/sql/item_timefunc.h	2005-08-12 11:07:57 -07:00
+++ 1.58/sql/item_timefunc.h	2005-08-17 17:22:41 -07:00
@@ -485,6 +485,20 @@
 };
 
 
+/*
+  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) {}
+  const char *func_name() const { return "sysdate"; }
+  virtual void store_now_in_TIME(TIME *now_time);
+};
+
+
 class Item_func_from_days :public Item_date
 {
 public:

--- 1.139/sql/lex.h	2005-08-11 18:58:18 -07:00
+++ 1.140/sql/lex.h	2005-08-17 17:22:41 -07:00
@@ -751,7 +751,7 @@
   { "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)},

--- 1.414/sql/sql_yacc.yy	2005-08-15 08:31:02 -07:00
+++ 1.415/sql/sql_yacc.yy	2005-08-17 17:22:41 -07:00
@@ -580,6 +580,7 @@
 %token  SUM_SYM
 %token  SUPER_SYM
 %token  SUSPEND_SYM
+%token  SYSDATE
 %token  TABLES
 %token  TABLESPACE
 %token  TABLE_SYM
@@ -4683,6 +4684,10 @@
 	  { $$= new Item_func_substr($3,$5); }
 	| SUBSTRING_INDEX '(' expr ',' expr ',' expr ')'
 	  { $$= new Item_func_substr_index($3,$5,$7); }
+	| SYSDATE optional_braces
+	  { $$= new Item_func_sysdate_local(); Lex->safe_to_cache_query=0;}
+	| SYSDATE '(' expr ')'
+	  { $$= new Item_func_sysdate_local($3); Lex->safe_to_cache_query=0;}
 	| TIME_SYM '(' expr ')'
 	  { $$= new Item_time_typecast($3); }
 	| TIMESTAMP '(' expr ')'

--- 1.44/mysql-test/r/func_time.result	2005-08-15 14:19:53 -07:00
+++ 1.45/mysql-test/r/func_time.result	2005-08-17 17:22:41 -07:00
@@ -720,3 +720,25 @@
 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;

--- 1.36/mysql-test/t/func_time.test	2005-07-28 07:09:48 -07:00
+++ 1.37/mysql-test/t/func_time.test	2005-08-17 17:22:41 -07:00
@@ -353,3 +353,37 @@
 # 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;
+
+# End of 5.0 tests
Thread
bk commit into 5.0 tree (jimw:1.1988) BUG#12562Jim Winstead18 Aug