Commit 921ac8af authored by dlenev@dlenev.mshome's avatar dlenev@dlenev.mshome

Implemented UTC_TIME, UTC_DATE and UTC_TIMESTAMP functions (WL#345)

parent a60acfcf
...@@ -1812,7 +1812,7 @@ AC_CHECK_FUNCS(alarm bmove \ ...@@ -1812,7 +1812,7 @@ AC_CHECK_FUNCS(alarm bmove \
gethostbyaddr_r gethostbyname_r getpwnam \ gethostbyaddr_r gethostbyname_r getpwnam \
bfill bzero bcmp strstr strpbrk strerror \ bfill bzero bcmp strstr strpbrk strerror \
tell atod memcpy memmove \ tell atod memcpy memmove \
setupterm strcasecmp sighold vidattr lrand48 localtime_r \ setupterm strcasecmp sighold vidattr lrand48 localtime_r gmtime_r \
sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \ sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \ pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \ pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
......
...@@ -463,6 +463,9 @@ typedef unsigned long long os_off_t; ...@@ -463,6 +463,9 @@ typedef unsigned long long os_off_t;
/* Define if you have the getwd function. */ /* Define if you have the getwd function. */
#define HAVE_GETWD 1 #define HAVE_GETWD 1
/* Define to 1 if you have the `gmtime_r' function. */
#define HAVE_GMTIME_R 1
/* Define if you have the index function. */ /* Define if you have the index function. */
#define HAVE_INDEX 1 #define HAVE_INDEX 1
......
...@@ -100,6 +100,8 @@ int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); ...@@ -100,6 +100,8 @@ int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
int pthread_attr_destroy(pthread_attr_t *connect_att); int pthread_attr_destroy(pthread_attr_t *connect_att);
struct tm *localtime_r(const time_t *timep,struct tm *tmp); struct tm *localtime_r(const time_t *timep,struct tm *tmp);
struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
...@@ -109,6 +111,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ ...@@ -109,6 +111,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#endif #endif
#define pthread_self() win_pthread_self #define pthread_self() win_pthread_self
#define HAVE_LOCALTIME_R 1 #define HAVE_LOCALTIME_R 1
#define HAVE_GMTIME_R 1
#define _REENTRANT 1 #define _REENTRANT 1
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1 #define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
...@@ -276,6 +279,8 @@ extern int my_pthread_create_detached; ...@@ -276,6 +279,8 @@ extern int my_pthread_create_detached;
#define USE_ALARM_THREAD #define USE_ALARM_THREAD
#undef HAVE_LOCALTIME_R #undef HAVE_LOCALTIME_R
#define HAVE_LOCALTIME_R #define HAVE_LOCALTIME_R
#undef HAVE_GMTIME_R
#define HAVE_GMTIME_R
#undef HAVE_PTHREAD_ATTR_SETSCOPE #undef HAVE_PTHREAD_ATTR_SETSCOPE
#define HAVE_PTHREAD_ATTR_SETSCOPE #define HAVE_PTHREAD_ATTR_SETSCOPE
#undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE /* If we are running linux */ #undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE /* If we are running linux */
...@@ -376,6 +381,10 @@ void *my_pthread_getspecific_imp(pthread_key_t key); ...@@ -376,6 +381,10 @@ void *my_pthread_getspecific_imp(pthread_key_t key);
struct tm *localtime_r(const time_t *clock, struct tm *res); struct tm *localtime_r(const time_t *clock, struct tm *res);
#endif #endif
#ifndef HAVE_GMTIME_R
struct tm *gmtime_r(const time_t *clock, struct tm *res);
#endif
#ifdef HAVE_PTHREAD_CONDATTR_CREATE #ifdef HAVE_PTHREAD_CONDATTR_CREATE
/* DCE threads on HPUX 10.20 */ /* DCE threads on HPUX 10.20 */
#define pthread_condattr_init pthread_condattr_create #define pthread_condattr_init pthread_condattr_create
......
...@@ -465,3 +465,21 @@ select date_add(time,INTERVAL 1 SECOND) from t1; ...@@ -465,3 +465,21 @@ select date_add(time,INTERVAL 1 SECOND) from t1;
date_add(time,INTERVAL 1 SECOND) date_add(time,INTERVAL 1 SECOND)
2006-07-08 00:00:01 2006-07-08 00:00:01
drop table t1; drop table t1;
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0
1
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0;
strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0
1
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0;
strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0
1
select strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0;
strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0
1
select strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0;
strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0
1
select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0;
strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0
1
...@@ -220,3 +220,12 @@ select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1; ...@@ -220,3 +220,12 @@ select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1;
# The following is not as one would expect... # The following is not as one would expect...
select date_add(time,INTERVAL 1 SECOND) from t1; select date_add(time,INTERVAL 1 SECOND) from t1;
drop table t1; drop table t1;
# Test SAPDB UTC_% functions. This part is TZ dependant (It is supposed that
# TZ variable set to GMT-3
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0;
select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0;
select strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0;
select strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0;
select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0;
...@@ -133,10 +133,13 @@ int my_sigwait(const sigset_t *set,int *sig) ...@@ -133,10 +133,13 @@ int my_sigwait(const sigset_t *set,int *sig)
/* localtime_r for SCO 3.2V4.2 */ /* localtime_r for SCO 3.2V4.2 */
#ifndef HAVE_LOCALTIME_R #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
extern pthread_mutex_t LOCK_localtime_r; extern pthread_mutex_t LOCK_localtime_r;
#endif
#if !defined(HAVE_LOCALTIME_R)
struct tm *localtime_r(const time_t *clock, struct tm *res) struct tm *localtime_r(const time_t *clock, struct tm *res)
{ {
struct tm *tmp; struct tm *tmp;
...@@ -148,6 +151,22 @@ struct tm *localtime_r(const time_t *clock, struct tm *res) ...@@ -148,6 +151,22 @@ struct tm *localtime_r(const time_t *clock, struct tm *res)
} }
#endif #endif
#if !defined(HAVE_GMTIME_R)
/*
Reentrant version of standard gmtime() function.
Needed on some systems which don't implement it.
*/
struct tm *gmtime_r(const time_t *clock, struct tm *res)
{
struct tm *tmp;
pthread_mutex_lock(&LOCK_localtime_r);
tmp= gmtime(clock);
*res= *tmp;
pthread_mutex_unlock(&LOCK_localtime_r);
return res;
}
#endif
/**************************************************************************** /****************************************************************************
** Replacement of sigwait if the system doesn't have one (like BSDI 3.0) ** Replacement of sigwait if the system doesn't have one (like BSDI 3.0)
......
...@@ -31,7 +31,7 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys); ...@@ -31,7 +31,7 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys);
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache, pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap, THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
THR_LOCK_net, THR_LOCK_charset; THR_LOCK_net, THR_LOCK_charset;
#ifndef HAVE_LOCALTIME_R #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
pthread_mutex_t LOCK_localtime_r; pthread_mutex_t LOCK_localtime_r;
#endif #endif
#ifndef HAVE_GETHOSTBYNAME_R #ifndef HAVE_GETHOSTBYNAME_R
...@@ -73,7 +73,7 @@ my_bool my_thread_global_init(void) ...@@ -73,7 +73,7 @@ my_bool my_thread_global_init(void)
#if defined( __WIN__) || defined(OS2) #if defined( __WIN__) || defined(OS2)
win_pthread_init(); win_pthread_init();
#endif #endif
#ifndef HAVE_LOCALTIME_R #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW); pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW);
#endif #endif
#ifndef HAVE_GETHOSTBYNAME_R #ifndef HAVE_GETHOSTBYNAME_R
...@@ -103,7 +103,7 @@ void my_thread_global_end(void) ...@@ -103,7 +103,7 @@ void my_thread_global_end(void)
pthread_mutex_destroy(&THR_LOCK_heap); pthread_mutex_destroy(&THR_LOCK_heap);
pthread_mutex_destroy(&THR_LOCK_net); pthread_mutex_destroy(&THR_LOCK_net);
pthread_mutex_destroy(&THR_LOCK_charset); pthread_mutex_destroy(&THR_LOCK_charset);
#ifndef HAVE_LOCALTIME_R #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
pthread_mutex_destroy(&LOCK_localtime_r); pthread_mutex_destroy(&LOCK_localtime_r);
#endif #endif
#ifndef HAVE_GETHOSTBYNAME_R #ifndef HAVE_GETHOSTBYNAME_R
......
...@@ -571,21 +571,21 @@ longlong Item_func_from_days::val_int() ...@@ -571,21 +571,21 @@ longlong Item_func_from_days::val_int()
void Item_func_curdate::fix_length_and_dec() void Item_func_curdate::fix_length_and_dec()
{ {
struct tm tm_tmp,*start; struct tm start;
time_t query_start=current_thd->query_start();
collation.set(default_charset()); collation.set(default_charset());
decimals=0; decimals=0;
max_length=10*default_charset()->mbmaxlen; max_length=10*default_charset()->mbmaxlen;
localtime_r(&query_start,&tm_tmp);
start=&tm_tmp; store_now_in_tm(current_thd->query_start(),&start);
value=(longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
((uint) start->tm_mon+1)*100+ value=(longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+
(uint) start->tm_mday); ((uint) start.tm_mon+1)*100+
(uint) start.tm_mday);
/* For getdate */ /* For getdate */
ltime.year= start->tm_year+1900; ltime.year= start.tm_year+1900;
ltime.month= start->tm_mon+1; ltime.month= start.tm_mon+1;
ltime.day= start->tm_mday; ltime.day= start.tm_mday;
ltime.hour= 0; ltime.hour= 0;
ltime.minute= 0; ltime.minute= 0;
ltime.second= 0; ltime.second= 0;
...@@ -594,6 +594,7 @@ void Item_func_curdate::fix_length_and_dec() ...@@ -594,6 +594,7 @@ void Item_func_curdate::fix_length_and_dec()
ltime.time_type=TIMESTAMP_DATE; ltime.time_type=TIMESTAMP_DATE;
} }
bool Item_func_curdate::get_date(TIME *res, bool Item_func_curdate::get_date(TIME *res,
bool fuzzy_date __attribute__((unused))) bool fuzzy_date __attribute__((unused)))
{ {
...@@ -601,6 +602,27 @@ bool Item_func_curdate::get_date(TIME *res, ...@@ -601,6 +602,27 @@ bool Item_func_curdate::get_date(TIME *res,
return 0; return 0;
} }
/*
Converts time in time_t to struct tm represenatation for local timezone.
Defines timezone (local) used for whole CURDATE function
*/
void Item_func_curdate_local::store_now_in_tm(time_t now, struct tm *now_tm)
{
localtime_r(&now,now_tm);
}
/*
Converts time in time_t to struct tm represenatation for UTC
Defines timezone (UTC) used for whole UTC_DATE function
*/
void Item_func_curdate_utc::store_now_in_tm(time_t now, struct tm *now_tm)
{
gmtime_r(&now,now_tm);
}
String *Item_func_curtime::val_str(String *str) String *Item_func_curtime::val_str(String *str)
{ {
str_value.set(buff,buff_length,default_charset()); str_value.set(buff,buff_length,default_charset());
...@@ -609,23 +631,43 @@ String *Item_func_curtime::val_str(String *str) ...@@ -609,23 +631,43 @@ String *Item_func_curtime::val_str(String *str)
void Item_func_curtime::fix_length_and_dec() void Item_func_curtime::fix_length_and_dec()
{ {
struct tm tm_tmp,*start; struct tm start;
time_t query_start=current_thd->query_start(); CHARSET_INFO *cs= default_charset();
CHARSET_INFO *cs=default_charset();
decimals=0; decimals=0;
max_length=8*cs->mbmaxlen; max_length=8*cs->mbmaxlen;
localtime_r(&query_start,&tm_tmp);
start=&tm_tmp;
collation.set(cs); collation.set(cs);
value=(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
(ulong) (((uint) start->tm_min)*100L+ store_now_in_tm(current_thd->query_start(),&start);
(uint) start->tm_sec));
value=(longlong) ((ulong) ((uint) start.tm_hour)*10000L+
(ulong) (((uint) start.tm_min)*100L+
(uint) start.tm_sec));
buff_length=cs->cset->snprintf(cs,buff,sizeof(buff),"%02d:%02d:%02d", buff_length=cs->cset->snprintf(cs,buff,sizeof(buff),"%02d:%02d:%02d",
(int) start->tm_hour, (int) start.tm_hour,
(int) start->tm_min, (int) start.tm_min,
(int) start->tm_sec); (int) start.tm_sec);
}
/*
Converts time in time_t to struct tm represenatation for local timezone.
Defines timezone (local) used for whole CURTIME function
*/
void Item_func_curtime_local::store_now_in_tm(time_t now, struct tm *now_tm)
{
localtime_r(&now,now_tm);
}
/*
Converts time in time_t to struct tm represenatation for UTC.
Defines timezone (UTC) used for whole UTC_TIME function
*/
void Item_func_curtime_utc::store_now_in_tm(time_t now, struct tm *now_tm)
{
gmtime_r(&now,now_tm);
} }
...@@ -638,37 +680,37 @@ String *Item_func_now::val_str(String *str) ...@@ -638,37 +680,37 @@ String *Item_func_now::val_str(String *str)
void Item_func_now::fix_length_and_dec() void Item_func_now::fix_length_and_dec()
{ {
struct tm tm_tmp,*start; struct tm start;
time_t query_start=current_thd->query_start();
CHARSET_INFO *cs= &my_charset_bin; CHARSET_INFO *cs= &my_charset_bin;
decimals=0; decimals=0;
max_length=19*cs->mbmaxlen; max_length=19*cs->mbmaxlen;
collation.set(cs); collation.set(cs);
localtime_r(&query_start,&tm_tmp);
start=&tm_tmp; store_now_in_tm(current_thd->query_start(),&start);
value=((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
(((uint) start->tm_mon+1)*100+ value=((longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+
(uint) start->tm_mday))*(longlong) 1000000L+ (((uint) start.tm_mon+1)*100+
(longlong) ((ulong) ((uint) start->tm_hour)*10000L+ (uint) start.tm_mday))*(longlong) 1000000L+
(ulong) (((uint) start->tm_min)*100L+ (longlong) ((ulong) ((uint) start.tm_hour)*10000L+
(uint) start->tm_sec))); (ulong) (((uint) start.tm_min)*100L+
(uint) start.tm_sec)));
buff_length= (uint) cs->cset->snprintf(cs,buff, sizeof(buff), buff_length= (uint) cs->cset->snprintf(cs,buff, sizeof(buff),
"%04d-%02d-%02d %02d:%02d:%02d", "%04d-%02d-%02d %02d:%02d:%02d",
((int) (start->tm_year+1900)) % 10000, ((int) (start.tm_year+1900)) % 10000,
(int) start->tm_mon+1, (int) start.tm_mon+1,
(int) start->tm_mday, (int) start.tm_mday,
(int) start->tm_hour, (int) start.tm_hour,
(int) start->tm_min, (int) start.tm_min,
(int) start->tm_sec); (int) start.tm_sec);
/* For getdate */ /* For getdate */
ltime.year= start->tm_year+1900; ltime.year= start.tm_year+1900;
ltime.month= start->tm_mon+1; ltime.month= start.tm_mon+1;
ltime.day= start->tm_mday; ltime.day= start.tm_mday;
ltime.hour= start->tm_hour; ltime.hour= start.tm_hour;
ltime.minute= start->tm_min; ltime.minute= start.tm_min;
ltime.second= start->tm_sec; ltime.second= start.tm_sec;
ltime.second_part=0; ltime.second_part=0;
ltime.neg=0; ltime.neg=0;
ltime.time_type=TIMESTAMP_FULL; ltime.time_type=TIMESTAMP_FULL;
...@@ -690,6 +732,26 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions) ...@@ -690,6 +732,26 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
} }
/*
Converts time in time_t to struct tm represenatation for local timezone.
Defines timezone (local) used for whole CURRENT_TIMESTAMP function
*/
void Item_func_now_local::store_now_in_tm(time_t now, struct tm *now_tm)
{
localtime_r(&now,now_tm);
}
/*
Converts time in time_t to struct tm represenatation for UTC.
Defines timezone (UTC) used for whole UTC_TIMESTAMP function
*/
void Item_func_now_utc::store_now_in_tm(time_t now, struct tm *now_tm)
{
gmtime_r(&now,now_tm);
}
String *Item_func_sec_to_time::val_str(String *str) String *Item_func_sec_to_time::val_str(String *str)
{ {
char buff[23*2]; char buff[23*2];
......
...@@ -350,6 +350,8 @@ class Item_date_func :public Item_str_func ...@@ -350,6 +350,8 @@ class Item_date_func :public Item_str_func
}; };
/* Abstract CURTIME function. Children should define what timezone is used */
class Item_func_curtime :public Item_func class Item_func_curtime :public Item_func
{ {
longlong value; longlong value;
...@@ -363,29 +365,77 @@ class Item_func_curtime :public Item_func ...@@ -363,29 +365,77 @@ class Item_func_curtime :public Item_func
double val() { return (double) value; } double val() { return (double) value; }
longlong val_int() { return value; } longlong val_int() { return value; }
String *val_str(String *str); String *val_str(String *str);
const char *func_name() const { return "curtime"; }
void fix_length_and_dec(); void fix_length_and_dec();
Field *tmp_table_field() { return result_field; } Field *tmp_table_field() { return result_field; }
Field *tmp_table_field(TABLE *t_arg) Field *tmp_table_field(TABLE *t_arg)
{ {
return (new Field_time(maybe_null, name, t_arg, default_charset())); return (new Field_time(maybe_null, name, t_arg, default_charset()));
} }
/*
Abstract method that defines which time zone is used for conversion.
Converts time from time_t representation to broken down representation
in struct tm using gmtime_r or localtime_r functions.
*/
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
}; };
class Item_func_curtime_local :public Item_func_curtime
{
public:
Item_func_curtime_local() :Item_func_curtime() {}
Item_func_curtime_local(Item *a) :Item_func_curtime(a) {}
const char *func_name() const { return "curtime"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
class Item_func_curtime_utc :public Item_func_curtime
{
public:
Item_func_curtime_utc() :Item_func_curtime() {}
Item_func_curtime_utc(Item *a) :Item_func_curtime(a) {}
const char *func_name() const { return "utc_time"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
/* Abstract CURDATE function. See also Item_func_curtime. */
class Item_func_curdate :public Item_date class Item_func_curdate :public Item_date
{ {
longlong value; longlong value;
TIME ltime; TIME ltime;
public: public:
Item_func_curdate() :Item_date() {} Item_func_curdate() :Item_date() {}
void set_result_from_tm(struct tm *now);
longlong val_int() { return (value) ; } longlong val_int() { return (value) ; }
const char *func_name() const { return "curdate"; } void fix_length_and_dec();
void fix_length_and_dec(); /* Retrieves curtime */
bool get_date(TIME *res,bool fuzzy_date); bool get_date(TIME *res,bool fuzzy_date);
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
};
class Item_func_curdate_local :public Item_func_curdate
{
public:
Item_func_curdate_local() :Item_func_curdate() {}
const char *func_name() const { return "curdate"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
}; };
class Item_func_curdate_utc :public Item_func_curdate
{
public:
Item_func_curdate_utc() :Item_func_curdate() {}
const char *func_name() const { return "utc_date"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
/* Abstract CURRENT_TIMESTAMP function. See also Item_func_curtime */
class Item_func_now :public Item_date_func class Item_func_now :public Item_date_func
{ {
longlong value; longlong value;
...@@ -400,9 +450,29 @@ class Item_func_now :public Item_date_func ...@@ -400,9 +450,29 @@ class Item_func_now :public Item_date_func
longlong val_int() { return value; } longlong val_int() { return value; }
int save_in_field(Field *to, bool no_conversions); int save_in_field(Field *to, bool no_conversions);
String *val_str(String *str); String *val_str(String *str);
const char *func_name() const { return "now"; }
void fix_length_and_dec(); void fix_length_and_dec();
bool get_date(TIME *res,bool fuzzy_date); bool get_date(TIME *res,bool fuzzy_date);
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
};
class Item_func_now_local :public Item_func_now
{
public:
Item_func_now_local() :Item_func_now() {}
Item_func_now_local(Item *a) :Item_func_now(a) {}
const char *func_name() const { return "now"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
};
class Item_func_now_utc :public Item_func_now
{
public:
Item_func_now_utc() :Item_func_now() {}
Item_func_now_utc(Item *a) :Item_func_now(a) {}
const char *func_name() const { return "utc_timestamp"; }
void store_now_in_tm(time_t now, struct tm *now_tm);
}; };
......
...@@ -404,6 +404,9 @@ static SYMBOL symbols[] = { ...@@ -404,6 +404,9 @@ static SYMBOL symbols[] = {
{ "USE_FRM", SYM(USE_FRM),0,0}, { "USE_FRM", SYM(USE_FRM),0,0},
{ "USER", SYM(USER),0,0}, { "USER", SYM(USER),0,0},
{ "USING", SYM(USING),0,0}, { "USING", SYM(USING),0,0},
{ "UTC_DATE", SYM(UTC_DATE_SYM),0,0},
{ "UTC_TIME", SYM(UTC_TIME_SYM),0,0},
{ "UTC_TIMESTAMP", SYM(UTC_TIMESTAMP_SYM),0,0},
{ "UPDATE", SYM(UPDATE_SYM),0,0}, { "UPDATE", SYM(UPDATE_SYM),0,0},
{ "USAGE", SYM(USAGE),0,0}, { "USAGE", SYM(USAGE),0,0},
{ "VALUE", SYM(VALUE_SYM),0,0}, { "VALUE", SYM(VALUE_SYM),0,0},
......
...@@ -526,6 +526,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -526,6 +526,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token UNIQUE_USERS %token UNIQUE_USERS
%token UNIX_TIMESTAMP %token UNIX_TIMESTAMP
%token USER %token USER
%token UTC_DATE_SYM
%token UTC_TIME_SYM
%token UTC_TIMESTAMP_SYM
%token WEEK_SYM %token WEEK_SYM
%token WHEN_SYM %token WHEN_SYM
%token WORK_SYM %token WORK_SYM
...@@ -2372,12 +2375,12 @@ simple_expr: ...@@ -2372,12 +2375,12 @@ simple_expr:
| CONCAT_WS '(' expr ',' expr_list ')' | CONCAT_WS '(' expr ',' expr_list ')'
{ $$= new Item_func_concat_ws($3, *$5); } { $$= new Item_func_concat_ws($3, *$5); }
| CURDATE optional_braces | CURDATE optional_braces
{ $$= new Item_func_curdate(); Lex->safe_to_cache_query=0; } { $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; }
| CURTIME optional_braces | CURTIME optional_braces
{ $$= new Item_func_curtime(); Lex->safe_to_cache_query=0; } { $$= new Item_func_curtime_local(); Lex->safe_to_cache_query=0; }
| CURTIME '(' expr ')' | CURTIME '(' expr ')'
{ {
$$= new Item_func_curtime($3); $$= new Item_func_curtime_local($3);
Lex->safe_to_cache_query=0; Lex->safe_to_cache_query=0;
} }
| DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')' | DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
...@@ -2539,9 +2542,9 @@ simple_expr: ...@@ -2539,9 +2542,9 @@ simple_expr:
{ $$= new Item_func_spatial_collection(* $3, { $$= new Item_func_spatial_collection(* $3,
Geometry::wkbMultiPolygon, Geometry::wkbPolygon ); } Geometry::wkbMultiPolygon, Geometry::wkbPolygon ); }
| NOW_SYM optional_braces | NOW_SYM optional_braces
{ $$= new Item_func_now(); Lex->safe_to_cache_query=0;} { $$= new Item_func_now_local(); Lex->safe_to_cache_query=0;}
| NOW_SYM '(' expr ')' | NOW_SYM '(' expr ')'
{ $$= new Item_func_now($3); Lex->safe_to_cache_query=0;} { $$= new Item_func_now_local($3); Lex->safe_to_cache_query=0;}
| PASSWORD '(' expr ')' | PASSWORD '(' expr ')'
{ $$= new Item_func_password($3); } { $$= new Item_func_password($3); }
| PASSWORD '(' expr ',' expr ')' | PASSWORD '(' expr ',' expr ')'
...@@ -2669,6 +2672,12 @@ simple_expr: ...@@ -2669,6 +2672,12 @@ simple_expr:
{ $$= new Item_func_unix_timestamp($3); } { $$= new Item_func_unix_timestamp($3); }
| USER '(' ')' | USER '(' ')'
{ $$= new Item_func_user(); Lex->safe_to_cache_query=0; } { $$= new Item_func_user(); Lex->safe_to_cache_query=0; }
| UTC_DATE_SYM optional_braces
{ $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
| UTC_TIME_SYM optional_braces
{ $$= new Item_func_curtime_utc(); Lex->safe_to_cache_query=0;}
| UTC_TIMESTAMP_SYM optional_braces
{ $$= new Item_func_now_utc(); Lex->safe_to_cache_query=0;}
| WEEK_SYM '(' expr ')' | WEEK_SYM '(' expr ')'
{ {
$$= new Item_func_week($3,new Item_int((char*) "0", $$= new Item_func_week($3,new Item_int((char*) "0",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment