Commit 299fc6a9 authored by unknown's avatar unknown

Scrum task 835 - text-to-datetime conversion function

parent d6f15e9d
SHOW GLOBAL VARIABLES LIKE "%_format%";
Variable_name Value
date_format %d.%m.%Y
datetime_format %Y/%d/%m-%H:%i:%s
default_week_format 0
time_format %H.%i.%s
SHOW SESSION VARIABLES LIKE "%_format%";
Variable_name Value
date_format %d.%m.%Y
datetime_format %Y/%d/%m-%H:%i:%s
default_week_format 0
time_format %H.%i.%s
SET date_format="%d.%m.%Y";
select CAST("01.01.2001" as DATE) as a;
a
01.01.2001
SET datetime_format="%d.%m.%Y %H.%i.%s";
select CAST("01.01.2001 05.12.06" as DATETIME) as a;
a
01.01.2001 05.12.06
SET time_format="%H.%i.%s";
select CAST("05.12.06" as TIME) as a;
a
05.12.06
SET datetime_format="%d.%m.%Y %h:%i:%s %p";
select CAST("01.01.2001 05:12:06AM" as DATETIME) as a;
a
01.01.2001 05:12:06 AM
select CAST("01.01.2001 05:12:06 PM" as DATETIME) as a;
a
01.01.2001 05:12:06 PM
SET time_format="%h:%i:%s %p";
select CAST("05:12:06 AM" as TIME) as a;
a
05:12:06 AM
select CAST("05:12:06.1234PM" as TIME) as a;
a
05:12:06.001234 PM
SET time_format="%h.%i.%s %p";
SET date_format='%d.%m.%y';
SET datetime_format="%d.%m.%y %h.%i.%s %p";
select CAST("12-12-06" as DATE) as a;
a
12.12.06
select adddate("01.01.97 11.59.59.000001 PM", 10);
adddate("01.01.97 11.59.59.000001 PM", 10)
11.01.97 11.59.59.000001 PM
select datediff("31.12.97 11.59:59.000001 PM","01.01.98");
datediff("31.12.97 11.59:59.000001 PM","01.01.98")
-1
select weekofyear("31.11.97 11:59:59.000001 PM");
weekofyear("31.11.97 11:59:59.000001 PM")
49
select makedate(1997,1);
makedate(1997,1)
01.01.97
select addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002");
addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002")
02.01.98 01.01.01.000001 AM
select maketime(23,11,12);
maketime(23,11,12)
11.11.12 PM
select timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM");
timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM")
8795.59.59.999999 PM
SET time_format="%H%i%s";
SET time_format="%h%i%s";
ERROR HY000: Unknown error
SET date_format='%d.%m.%d';
ERROR HY000: Unknown error
SET datetime_format="%d.%m.%y %h.%i.%s";
ERROR HY000: Unknown error
SET GLOBAL date_format=default;
SHOW GLOBAL VARIABLES LIKE "date_format%";
Variable_name Value
date_format %d.%m.%Y
SET GLOBAL time_format=default;
SHOW GLOBAL VARIABLES LIKE "time_format%";
Variable_name Value
time_format %H.%i.%s
SET GLOBAL datetime_format=default;
SHOW GLOBAL VARIABLES LIKE "datetime_format%";
Variable_name Value
datetime_format %Y/%d/%m-%H:%i:%s
SET date_format=default;
SHOW SESSION VARIABLES LIKE "date_format%";
Variable_name Value
date_format %d.%m.%Y
SET time_format=default;
SHOW SESSION VARIABLES LIKE "time_format%";
Variable_name Value
time_format %H.%i.%s
SET datetime_format=default;
SHOW SESSION VARIABLES LIKE "datetime_format%";
Variable_name Value
datetime_format %Y/%d/%m-%H:%i:%s
SET time_format='%i:%s:%H';
select cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME);
cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME)
59:59:12
SET GLOBAL date_format='%Y-%m-%d';
SET GLOBAL time_format='%H:%i:%s';
SET GLOBAL datetime_format='%Y-%m-%d %H:%i:%s';
SET date_format='%Y-%m-%d';
SET time_format='%H:%i:%s';
SET datetime_format='%Y-%m-%d %H:%i:%s';
select str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S");
str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S")
2001-01-15 12:59:59
select str_to_date("15 September 2001", "%d %M %Y");
str_to_date("15 September 2001", "%d %M %Y")
2001-09-15 00:00:00
select str_to_date("15 Septembeb 2001", "%d %M %Y");
str_to_date("15 Septembeb 2001", "%d %M %Y")
NULL
select str_to_date("15 MAY 2001", "%d %b %Y");
str_to_date("15 MAY 2001", "%d %b %Y")
2001-05-15 00:00:00
select str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y");
str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y")
2001-05-15 00:00:00
select str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y");
str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y")
NULL
select str_to_date("Sundai 15 MA", "%W %d %b %Y");
str_to_date("Sundai 15 MA", "%W %d %b %Y")
NULL
select str_to_date("Tuesday 52 2001", "%W %V %X");
str_to_date("Tuesday 52 2001", "%W %V %X")
NULL
select str_to_date("Sunday 01 2001", "%W %V %X");
str_to_date("Sunday 01 2001", "%W %V %X")
NULL
select str_to_date("Tuesday 00 2002", "%W %U %Y");
str_to_date("Tuesday 00 2002", "%W %U %Y")
2002-01-01 00:00:00
select str_to_date("Thursday 53 1998", "%W %u %Y");
str_to_date("Thursday 53 1998", "%W %u %Y")
1998-12-31 00:00:00
select str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S");
str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S")
2001-01-15 00:00:00
select str_to_date("15-01-20", "%d-%m-%Y");
str_to_date("15-01-20", "%d-%m-%Y")
NULL
select str_to_date("15-2001-1", "%d-%Y-%c");
str_to_date("15-2001-1", "%d-%Y-%c")
2001-01-15 00:00:00
select get_format(DATE, 'USA') as a;
a
%m.%d.%Y
select get_format(TIME, 'internal') as a;
a
%H%i%s
select get_format(DATETIME, 'eur') as a;
a
%Y-%m-%d-%H.%i.%s
--date_format=%d.%m.%Y --time_format=%H.%i.%s --datetime_format=%Y/%d/%m-%H:%i:%s
SHOW GLOBAL VARIABLES LIKE "%_format%";
SHOW SESSION VARIABLES LIKE "%_format%";
SET date_format="%d.%m.%Y";
select CAST("01.01.2001" as DATE) as a;
SET datetime_format="%d.%m.%Y %H.%i.%s";
select CAST("01.01.2001 05.12.06" as DATETIME) as a;
SET time_format="%H.%i.%s";
select CAST("05.12.06" as TIME) as a;
SET datetime_format="%d.%m.%Y %h:%i:%s %p";
select CAST("01.01.2001 05:12:06AM" as DATETIME) as a;
select CAST("01.01.2001 05:12:06 PM" as DATETIME) as a;
SET time_format="%h:%i:%s %p";
select CAST("05:12:06 AM" as TIME) as a;
select CAST("05:12:06.1234PM" as TIME) as a;
SET time_format="%h.%i.%s %p";
SET date_format='%d.%m.%y';
SET datetime_format="%d.%m.%y %h.%i.%s %p";
select CAST("12-12-06" as DATE) as a;
select adddate("01.01.97 11.59.59.000001 PM", 10);
select datediff("31.12.97 11.59:59.000001 PM","01.01.98");
select weekofyear("31.11.97 11:59:59.000001 PM");
select makedate(1997,1);
select addtime("31.12.97 11.59.59.999999 PM", "1 1.1.1.000002");
select maketime(23,11,12);
select timediff("01.01.97 11:59:59.000001 PM","31.12.95 11:59:59.000002 PM");
SET time_format="%H%i%s";
--error 1105
SET time_format="%h%i%s";
--error 1105
SET date_format='%d.%m.%d';
--error 1105
SET datetime_format="%d.%m.%y %h.%i.%s";
SET GLOBAL date_format=default;
SHOW GLOBAL VARIABLES LIKE "date_format%";
SET GLOBAL time_format=default;
SHOW GLOBAL VARIABLES LIKE "time_format%";
SET GLOBAL datetime_format=default;
SHOW GLOBAL VARIABLES LIKE "datetime_format%";
SET date_format=default;
SHOW SESSION VARIABLES LIKE "date_format%";
SET time_format=default;
SHOW SESSION VARIABLES LIKE "time_format%";
SET datetime_format=default;
SHOW SESSION VARIABLES LIKE "datetime_format%";
SET time_format='%i:%s:%H';
select cast(str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S") as TIME);
SET GLOBAL date_format='%Y-%m-%d';
SET GLOBAL time_format='%H:%i:%s';
SET GLOBAL datetime_format='%Y-%m-%d %H:%i:%s';
SET date_format='%Y-%m-%d';
SET time_format='%H:%i:%s';
SET datetime_format='%Y-%m-%d %H:%i:%s';
select str_to_date("15-01-2001 12:59:59", "%d-%m-%Y %H:%i:%S");
select str_to_date("15 September 2001", "%d %M %Y");
select str_to_date("15 Septembeb 2001", "%d %M %Y");
select str_to_date("15 MAY 2001", "%d %b %Y");
select str_to_date("Sunday 15 MAY 2001", "%W %d %b %Y");
select str_to_date("Sundai 15 MAY 2001", "%W %d %b %Y");
select str_to_date("Sundai 15 MA", "%W %d %b %Y");
select str_to_date("Tuesday 52 2001", "%W %V %X");
select str_to_date("Sunday 01 2001", "%W %V %X");
select str_to_date("Tuesday 00 2002", "%W %U %Y");
select str_to_date("Thursday 53 1998", "%W %u %Y");
select str_to_date("15-01-2001", "%d-%m-%Y %H:%i:%S");
select str_to_date("15-01-20", "%d-%m-%Y");
select str_to_date("15-2001-1", "%d-%Y-%c");
select get_format(DATE, 'USA') as a;
select get_format(TIME, 'internal') as a;
select get_format(DATETIME, 'eur') as a;
...@@ -279,7 +279,8 @@ bool Field::get_date(TIME *ltime,bool fuzzydate) ...@@ -279,7 +279,8 @@ bool Field::get_date(TIME *ltime,bool fuzzydate)
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res; String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res;
if (!(res=val_str(&tmp,&tmp2)) || if (!(res=val_str(&tmp,&tmp2)) ||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate,current_thd)<=
WRONG_TIMESTAMP_FULL)
return 1; return 1;
return 0; return 0;
} }
...@@ -289,7 +290,7 @@ bool Field::get_time(TIME *ltime) ...@@ -289,7 +290,7 @@ bool Field::get_time(TIME *ltime)
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res; String tmp(buff,sizeof(buff),&my_charset_bin),tmp2,*res;
if (!(res=val_str(&tmp,&tmp2)) || if (!(res=val_str(&tmp,&tmp2)) ||
str_to_time(res->ptr(),res->length(),ltime)) str_to_time(res->ptr(),res->length(),ltime,current_thd))
return 1; return 1;
return 0; return 0;
} }
...@@ -299,28 +300,29 @@ bool Field::get_time(TIME *ltime) ...@@ -299,28 +300,29 @@ bool Field::get_time(TIME *ltime)
void Field::store_time(TIME *ltime,timestamp_type type) void Field::store_time(TIME *ltime,timestamp_type type)
{ {
char buff[25]; char buff[25];
String tmp((char*) buff,sizeof(buff),&my_charset_bin);
DATETIME_FORMAT *tmp_format= 0;
bool is_time_only= 0;
switch (type) { switch (type) {
case TIMESTAMP_NONE: case TIMESTAMP_NONE:
case WRONG_TIMESTAMP_FULL:
store("",0,&my_charset_bin); // Probably an error store("",0,&my_charset_bin); // Probably an error
break; return;
case TIMESTAMP_DATE: case TIMESTAMP_DATE:
sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day); tmp_format= &t_datetime_frm(current_thd, DATE_FORMAT_TYPE).datetime_format;
store(buff,10,&my_charset_bin);
break; break;
case TIMESTAMP_FULL: case TIMESTAMP_FULL:
sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d", tmp_format=&t_datetime_frm(current_thd,DATETIME_FORMAT_TYPE).datetime_format;
ltime->year,ltime->month,ltime->day,
ltime->hour,ltime->minute,ltime->second);
store(buff,19,&my_charset_bin);
break; break;
case TIMESTAMP_TIME: case TIMESTAMP_TIME:
{ tmp_format= &t_datetime_frm(current_thd, TIME_FORMAT_TYPE).datetime_format;
ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d", is_time_only= 1;
ltime->hour,ltime->minute,ltime->second));
store(buff,(uint) length, &my_charset_bin);
break; break;
} }
} make_datetime(&tmp, ltime, is_time_only, 0,
tmp_format->format, tmp_format->format_length, 1);
store(tmp.ptr(),tmp.length(),&my_charset_bin);
} }
...@@ -2684,7 +2686,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, ...@@ -2684,7 +2686,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
long tmp=(long) str_to_timestamp(from,len); long tmp=(long) str_to_timestamp(from,len,current_thd);
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) if (table->db_low_byte_first)
{ {
...@@ -3018,7 +3020,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3018,7 +3020,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
TIME ltime; TIME ltime;
long tmp; long tmp;
int error= 0; int error= 0;
if (str_to_time(from,len,&ltime)) if (str_to_time(from,len,&ltime,current_thd))
{ {
tmp=0L; tmp=0L;
error= 1; error= 1;
...@@ -3127,19 +3129,25 @@ longlong Field_time::val_int(void) ...@@ -3127,19 +3129,25 @@ longlong Field_time::val_int(void)
String *Field_time::val_str(String *val_buffer, String *Field_time::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
TIME ltime;
val_buffer->alloc(16); val_buffer->alloc(16);
long tmp=(long) sint3korr(ptr); long tmp=(long) sint3korr(ptr);
const char *sign=""; const char *sign="";
ltime.neg= 0;
if (tmp < 0) if (tmp < 0)
{ {
tmp= -tmp; tmp= -tmp;
sign= "-"; ltime.neg= 1;
} }
long length= my_sprintf((char*) val_buffer->ptr(), DATETIME_FORMAT *tmp_format= (&t_datetime_frm
((char*) val_buffer->ptr(),"%s%02d:%02d:%02d", (current_thd, TIME_FORMAT_TYPE).datetime_format);
sign,(int) (tmp/10000), (int) (tmp/100 % 100), ltime.day= (uint) 0;
(int) (tmp % 100))); ltime.hour= (uint) (tmp/10000);
val_buffer->length(length); ltime.minute= (uint) (tmp/100 % 100);
ltime.second= (uint) (tmp % 100);
make_datetime(val_buffer, &ltime, 0, 0,
tmp_format->format,
tmp_format->format_length, 1);
return val_buffer; return val_buffer;
} }
...@@ -3305,7 +3313,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) ...@@ -3305,7 +3313,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
TIME l_time; TIME l_time;
uint32 tmp; uint32 tmp;
int error= 0; int error= 0;
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE) if (str_to_TIME(from,len,&l_time,1,current_thd) <= WRONG_TIMESTAMP_FULL)
{ {
tmp=0; tmp=0;
error= 1; error= 1;
...@@ -3415,6 +3423,7 @@ longlong Field_date::val_int(void) ...@@ -3415,6 +3423,7 @@ longlong Field_date::val_int(void)
String *Field_date::val_str(String *val_buffer, String *Field_date::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
TIME ltime;
val_buffer->alloc(field_length); val_buffer->alloc(field_length);
val_buffer->length(field_length); val_buffer->length(field_length);
int32 tmp; int32 tmp;
...@@ -3424,9 +3433,15 @@ String *Field_date::val_str(String *val_buffer, ...@@ -3424,9 +3433,15 @@ String *Field_date::val_str(String *val_buffer,
else else
#endif #endif
longget(tmp,ptr); longget(tmp,ptr);
sprintf((char*) val_buffer->ptr(),"%04d-%02d-%02d", DATETIME_FORMAT *tmp_format= (&t_datetime_frm
(int) ((uint32) tmp/10000L % 10000), (int) ((uint32) tmp/100 % 100), (current_thd, DATE_FORMAT_TYPE).datetime_format);
(int) ((uint32) tmp % 100)); ltime.neg= 0;
ltime.year= (int) ((uint32) tmp/10000L % 10000);
ltime.month= (int) ((uint32) tmp/100 % 100);
ltime.day= (int) ((uint32) tmp % 100);
make_datetime(val_buffer, &ltime, 0, 0,
tmp_format->format,
tmp_format->format_length, 1);
return val_buffer; return val_buffer;
} }
...@@ -3485,7 +3500,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -3485,7 +3500,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
TIME l_time; TIME l_time;
long tmp; long tmp;
int error= 0; int error= 0;
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE) if (str_to_TIME(from,len,&l_time,1,current_thd) <= WRONG_TIMESTAMP_FULL)
{ {
tmp=0L; tmp=0L;
error= 1; error= 1;
...@@ -3654,7 +3669,7 @@ void Field_newdate::sql_type(String &res) const ...@@ -3654,7 +3669,7 @@ void Field_newdate::sql_type(String &res) const
int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
longlong tmp=str_to_datetime(from,len,1); longlong tmp=str_to_datetime(from,len,1,current_thd);
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) if (table->db_low_byte_first)
{ {
......
...@@ -46,7 +46,7 @@ Item::Item(): ...@@ -46,7 +46,7 @@ Item::Item():
collation.set(default_charset(), DERIVATION_COERCIBLE); collation.set(default_charset(), DERIVATION_COERCIBLE);
name= 0; name= 0;
decimals= 0; max_length= 0; decimals= 0; max_length= 0;
THD *thd= current_thd; thd= current_thd;
next= thd->free_list; // Put in free list next= thd->free_list; // Put in free list
thd->free_list= this; thd->free_list= this;
/* /*
...@@ -69,7 +69,7 @@ Item::Item(): ...@@ -69,7 +69,7 @@ Item::Item():
Used for duplicating lists in processing queries with temporary Used for duplicating lists in processing queries with temporary
tables tables
*/ */
Item::Item(THD *thd, Item &item): Item::Item(THD *c_thd, Item &item):
str_value(item.str_value), str_value(item.str_value),
name(item.name), name(item.name),
max_length(item.max_length), max_length(item.max_length),
...@@ -82,7 +82,8 @@ Item::Item(THD *thd, Item &item): ...@@ -82,7 +82,8 @@ Item::Item(THD *thd, Item &item):
fixed(item.fixed), fixed(item.fixed),
collation(item.collation) collation(item.collation)
{ {
next=thd->free_list; // Put in free list next=c_thd->free_list; // Put in free list
thd= c_thd;
thd->free_list= this; thd->free_list= this;
} }
...@@ -174,7 +175,8 @@ bool Item::get_date(TIME *ltime,bool fuzzydate) ...@@ -174,7 +175,8 @@ bool Item::get_date(TIME *ltime,bool fuzzydate)
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff), &my_charset_bin),*res; String tmp(buff,sizeof(buff), &my_charset_bin),*res;
if (!(res=val_str(&tmp)) || if (!(res=val_str(&tmp)) ||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate, thd) <=
WRONG_TIMESTAMP_FULL)
{ {
bzero((char*) ltime,sizeof(*ltime)); bzero((char*) ltime,sizeof(*ltime));
return 1; return 1;
...@@ -192,7 +194,7 @@ bool Item::get_time(TIME *ltime) ...@@ -192,7 +194,7 @@ bool Item::get_time(TIME *ltime)
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff),&my_charset_bin),*res; String tmp(buff,sizeof(buff),&my_charset_bin),*res;
if (!(res=val_str(&tmp)) || if (!(res=val_str(&tmp)) ||
str_to_time(res->ptr(),res->length(),ltime)) str_to_time(res->ptr(),res->length(),ltime, thd))
{ {
bzero((char*) ltime,sizeof(*ltime)); bzero((char*) ltime,sizeof(*ltime));
return 1; return 1;
...@@ -673,30 +675,28 @@ String *Item_param::query_val_str(String* str) ...@@ -673,30 +675,28 @@ String *Item_param::query_val_str(String* str)
} }
else else
{ {
char buff[25]; DATETIME_FORMAT *tmp_format= 0;
bool is_time_only= 0;
switch (ltime.time_type) { switch (ltime.time_type) {
case TIMESTAMP_NONE: case TIMESTAMP_NONE:
case WRONG_TIMESTAMP_FULL:
break; break;
case TIMESTAMP_DATE: case TIMESTAMP_DATE:
sprintf(buff, "%04d-%02d-%02d", tmp_format= &t_datetime_frm(thd, DATE_FORMAT_TYPE).datetime_format;
ltime.year,ltime.month,ltime.day);
str->append(buff, 10);
break; break;
case TIMESTAMP_FULL: case TIMESTAMP_FULL:
sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d", tmp_format= &t_datetime_frm(thd, DATETIME_FORMAT_TYPE).datetime_format;
ltime.year,ltime.month,ltime.day,
ltime.hour,ltime.minute,ltime.second);
str->append(buff, 19);
break; break;
case TIMESTAMP_TIME: case TIMESTAMP_TIME:
{ {
sprintf(buff, "%02d:%02d:%02d", tmp_format= &t_datetime_frm(thd, TIME_FORMAT_TYPE).datetime_format;
ltime.hour,ltime.minute,ltime.second); is_time_only= 1;
str->append(buff, 8);
break; break;
} }
} }
make_datetime(str, &ltime, is_time_only, 0,
tmp_format->format, tmp_format->format_length, 0);
} }
str->append("'"); str->append("'");
} }
......
...@@ -114,6 +114,14 @@ class Item { ...@@ -114,6 +114,14 @@ class Item {
my_bool fixed; /* If item fixed with fix_fields */ my_bool fixed; /* If item fixed with fix_fields */
DTCollation collation; DTCollation collation;
/*
thd is current_thd value. Like some other Item's fields it
will be a problem for using one Item in different threads
(as stored procedures may want to do in the future)
*/
THD *thd;
// alloc & destruct is done as start of select using sql_alloc // alloc & destruct is done as start of select using sql_alloc
Item(); Item();
/* /*
...@@ -124,7 +132,7 @@ class Item { ...@@ -124,7 +132,7 @@ class Item {
top AND/OR ctructure of WHERE clause to protect it of top AND/OR ctructure of WHERE clause to protect it of
optimisation changes in prepared statements optimisation changes in prepared statements
*/ */
Item(THD *thd, Item &item); Item(THD *c_thd, Item &item);
virtual ~Item() { name=0; } /*lint -e1509 */ virtual ~Item() { name=0; } /*lint -e1509 */
void set_name(const char *str,uint length, CHARSET_INFO *cs); void set_name(const char *str,uint length, CHARSET_INFO *cs);
void init_make_field(Send_field *tmp_field,enum enum_field_types type); void init_make_field(Send_field *tmp_field,enum enum_field_types type);
......
...@@ -701,3 +701,8 @@ Item *create_func_maketime(Item* a,Item* b,Item* c) ...@@ -701,3 +701,8 @@ Item *create_func_maketime(Item* a,Item* b,Item* c)
{ {
return new Item_func_maketime(a, b, c); return new Item_func_maketime(a, b, c);
} }
Item *create_func_str_to_date(Item* a,Item* b)
{
return new Item_func_str_to_date(a, b);
}
...@@ -149,3 +149,4 @@ Item *create_func_addtime(Item* a,Item* b); ...@@ -149,3 +149,4 @@ Item *create_func_addtime(Item* a,Item* b);
Item *create_func_subtime(Item* a,Item* b); Item *create_func_subtime(Item* a,Item* b);
Item *create_func_timediff(Item* a,Item* b); Item *create_func_timediff(Item* a,Item* b);
Item *create_func_maketime(Item* a,Item* b,Item* c); Item *create_func_maketime(Item* a,Item* b,Item* c);
Item *create_func_str_to_date(Item* a,Item* b);
This diff is collapsed.
...@@ -763,3 +763,46 @@ class Item_func_microsecond :public Item_int_func ...@@ -763,3 +763,46 @@ class Item_func_microsecond :public Item_int_func
maybe_null=1; maybe_null=1;
} }
}; };
enum datetime_format
{
USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT
};
enum datetime_format_types
{
DATE_FORMAT_TYPE= 0, TIME_FORMAT_TYPE, DATETIME_FORMAT_TYPE
};
class Item_func_get_format :public Item_str_func
{
const datetime_format_types tm_format;
public:
Item_func_get_format(datetime_format_types type_arg1, Item *a)
:Item_str_func(a), tm_format(type_arg1) {}
String *val_str(String *str);
const char *func_name() const { return "get_format"; }
void fix_length_and_dec()
{
decimals=0;
max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
}
};
class Item_func_str_to_date :public Item_str_func
{
public:
Item_func_str_to_date(Item *a, Item *b)
:Item_str_func(a, b) {}
String *val_str(String *str);
const char *func_name() const { return "str_to_date"; }
void fix_length_and_dec()
{
decimals=0;
max_length=29*MY_CHARSET_BIN_MB_MAXLEN;
}
};
...@@ -176,6 +176,7 @@ static SYMBOL symbols[] = { ...@@ -176,6 +176,7 @@ static SYMBOL symbols[] = {
{ "FUNCTION", SYM(UDF_SYM),0,0}, { "FUNCTION", SYM(UDF_SYM),0,0},
{ "GEOMETRY", SYM(GEOMETRY_SYM),0,0}, { "GEOMETRY", SYM(GEOMETRY_SYM),0,0},
{ "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION),0,0}, { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION),0,0},
{ "GET_FORMAT", SYM(GET_FORMAT),0,0},
{ "GLOBAL", SYM(GLOBAL_SYM),0,0}, { "GLOBAL", SYM(GLOBAL_SYM),0,0},
{ "GRANT", SYM(GRANT),0,0}, { "GRANT", SYM(GRANT),0,0},
{ "GRANTS", SYM(GRANTS),0,0}, { "GRANTS", SYM(GRANTS),0,0},
...@@ -634,6 +635,7 @@ static SYMBOL sql_functions[] = { ...@@ -634,6 +635,7 @@ static SYMBOL sql_functions[] = {
{ "STARTPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_startpoint)}, { "STARTPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_startpoint)},
{ "STD", SYM(STD_SYM),0,0}, { "STD", SYM(STD_SYM),0,0},
{ "STDDEV", SYM(STD_SYM),0,0}, { "STDDEV", SYM(STD_SYM),0,0},
{ "STR_TO_DATE", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)},
{ "STRCMP", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)}, { "STRCMP", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)},
{ "SUBSTR", SYM(SUBSTRING),0,0}, { "SUBSTR", SYM(SUBSTRING),0,0},
{ "SUBSTRING", SYM(SUBSTRING),0,0}, { "SUBSTRING", SYM(SUBSTRING),0,0},
......
...@@ -800,6 +800,13 @@ extern struct system_variables global_system_variables; ...@@ -800,6 +800,13 @@ extern struct system_variables global_system_variables;
extern struct system_variables max_system_variables; extern struct system_variables max_system_variables;
extern struct rand_struct sql_rand; extern struct rand_struct sql_rand;
#define g_datetime_frm(a) (global_system_variables.datetime_formats[(a)])
#define t_datetime_frm(a, b) ((a)->variables.datetime_formats[(b)])
extern const char *datetime_formats[4][5];
extern const char *opt_datetime_format_names[3];
extern const char *opt_datetime_formats[3];
/* optional things, have_* variables */ /* optional things, have_* variables */
extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db; extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db;
...@@ -863,14 +870,24 @@ void get_date_from_daynr(long daynr,uint *year, uint *month, ...@@ -863,14 +870,24 @@ void get_date_from_daynr(long daynr,uint *year, uint *month,
uint *day); uint *day);
void init_time(void); void init_time(void);
long my_gmt_sec(TIME *, long *current_timezone); long my_gmt_sec(TIME *, long *current_timezone);
time_t str_to_timestamp(const char *str,uint length); time_t str_to_timestamp(const char *str,uint length, THD *thd);
bool str_to_time(const char *str,uint length,TIME *l_time); bool str_to_time(const char *str,uint length,TIME *l_time, THD *thd);
longlong str_to_datetime(const char *str,uint length,bool fuzzy_date); longlong str_to_datetime(const char *str,uint length,bool fuzzy_date, THD *thd);
timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time, timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time,
bool fuzzy_date); bool fuzzy_date, THD *thd);
void localtime_to_TIME(TIME *to, struct tm *from); void localtime_to_TIME(TIME *to, struct tm *from);
void calc_time_from_sec(TIME *to, long seconds, long microseconds); void calc_time_from_sec(TIME *to, long seconds, long microseconds);
extern DATETIME_FORMAT *make_format(DATETIME_FORMAT *datetime_format,
datetime_format_types format_type,
const char *format_str,
uint format_length, bool is_alloc);
extern String *make_datetime(String *str, TIME *l_time,
const bool is_time_only,
const bool add_second_frac,
const char *ptr, uint format_length,
bool set_len_to_zero);
int test_if_number(char *str,int *res,bool allow_wildcards); int test_if_number(char *str,int *res,bool allow_wildcards);
void change_byte(byte *,uint,char,char); void change_byte(byte *,uint,char,char);
extern "C" void unireg_abort(int exit_code); extern "C" void unireg_abort(int exit_code);
......
...@@ -310,6 +310,12 @@ char* log_error_file_ptr= log_error_file; ...@@ -310,6 +310,12 @@ char* log_error_file_ptr= log_error_file;
char mysql_real_data_home[FN_REFLEN], char mysql_real_data_home[FN_REFLEN],
language[LIBLEN],reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], language[LIBLEN],reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file;
const char *opt_datetime_formats[3];
const char *opt_datetime_format_names[3]= {"date_format",
"time_format",
"datetime_format"};
char *language_ptr, *default_collation_name, *default_character_set_name; char *language_ptr, *default_collation_name, *default_character_set_name;
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
...@@ -893,6 +899,9 @@ void clean_up(bool print_message) ...@@ -893,6 +899,9 @@ void clean_up(bool print_message)
#ifdef USE_RAID #ifdef USE_RAID
end_raid(); end_raid();
#endif #endif
g_datetime_frm(DATE_FORMAT_TYPE).clean();
g_datetime_frm(TIME_FORMAT_TYPE).clean();
g_datetime_frm(DATETIME_FORMAT_TYPE).clean();
if (defaults_argv) if (defaults_argv)
free_defaults(defaults_argv); free_defaults(defaults_argv);
free_tmpdir(&mysql_tmpdir_list); free_tmpdir(&mysql_tmpdir_list);
...@@ -1976,6 +1985,36 @@ bool open_log(MYSQL_LOG *log, const char *hostname, ...@@ -1976,6 +1985,36 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
} }
int init_global_datetime_format(datetime_format_types format_type, bool is_alloc)
{
const char *format_str= opt_datetime_formats[format_type];
uint format_length= 0;
DATETIME_FORMAT *tmp_format= &g_datetime_frm(format_type).datetime_format;
if (format_str)
{
format_str= opt_datetime_formats[format_type];
format_length= strlen(format_str);
}
else
{
format_str= datetime_formats[format_type][ISO_FORMAT];
format_length= strlen(datetime_formats[format_type][ISO_FORMAT]);
opt_datetime_formats[format_type]= format_str;
}
if (make_format(tmp_format, format_type, format_str,
format_length, is_alloc))
{
g_datetime_frm(format_type).name= opt_datetime_format_names[format_type];
g_datetime_frm(format_type).name_length=
strlen(opt_datetime_format_names[format_type]);
g_datetime_frm(format_type).format_type= format_type;
return 0;
}
return 1;
}
static int init_common_variables(const char *conf_file_name, int argc, static int init_common_variables(const char *conf_file_name, int argc,
char **argv, const char **groups) char **argv, const char **groups)
{ {
...@@ -2089,6 +2128,11 @@ static int init_common_variables(const char *conf_file_name, int argc, ...@@ -2089,6 +2128,11 @@ static int init_common_variables(const char *conf_file_name, int argc,
global_system_variables.character_set_client= default_charset_info; global_system_variables.character_set_client= default_charset_info;
global_system_variables.collation_connection= default_charset_info; global_system_variables.collation_connection= default_charset_info;
if (init_global_datetime_format(DATE_FORMAT_TYPE, 1) ||
init_global_datetime_format(TIME_FORMAT_TYPE, 1) ||
init_global_datetime_format(DATETIME_FORMAT_TYPE, 1))
return 1;
if (use_temp_pool && bitmap_init(&temp_pool,1024,1)) if (use_temp_pool && bitmap_init(&temp_pool,1024,1))
return 1; return 1;
return 0; return 0;
...@@ -3533,7 +3577,10 @@ enum options ...@@ -3533,7 +3577,10 @@ enum options
OPT_DEFAULT_WEEK_FORMAT, OPT_DEFAULT_WEEK_FORMAT,
OPT_GROUP_CONCAT_MAX_LEN, OPT_GROUP_CONCAT_MAX_LEN,
OPT_DEFAULT_COLLATION, OPT_DEFAULT_COLLATION,
OPT_SECURE_AUTH OPT_SECURE_AUTH,
OPT_DATE_FORMAT,
OPT_TIME_FORMAT,
OPT_DATETIME_FORMAT
}; };
...@@ -4444,6 +4491,21 @@ The minimum value for this variable is 4096.", ...@@ -4444,6 +4491,21 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.default_week_format, (gptr*) &global_system_variables.default_week_format,
(gptr*) &max_system_variables.default_week_format, (gptr*) &max_system_variables.default_week_format,
0, GET_ULONG, REQUIRED_ARG, 0, 0, 3L, 0, 1, 0}, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3L, 0, 1, 0},
{ "date-format", OPT_DATE_FORMAT,
"The DATE format.",
(gptr*) &opt_datetime_formats[DATE_FORMAT_TYPE],
(gptr*) &opt_datetime_formats[DATE_FORMAT_TYPE],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "datetime-format", OPT_DATETIME_FORMAT,
"The DATETIME/TIMESTAMP format.",
(gptr*) &opt_datetime_formats[DATETIME_FORMAT_TYPE],
(gptr*) &opt_datetime_formats[DATETIME_FORMAT_TYPE],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "time-format", OPT_TIME_FORMAT,
"The TIME format.",
(gptr*) &opt_datetime_formats[TIME_FORMAT_TYPE],
(gptr*) &opt_datetime_formats[TIME_FORMAT_TYPE],
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
}; };
...@@ -4821,6 +4883,10 @@ static void mysql_init_variables(void) ...@@ -4821,6 +4883,10 @@ static void mysql_init_variables(void)
max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
global_system_variables.old_passwords= 0; global_system_variables.old_passwords= 0;
init_global_datetime_format(DATE_FORMAT_TYPE, 0);
init_global_datetime_format(TIME_FORMAT_TYPE, 0);
init_global_datetime_format(DATETIME_FORMAT_TYPE, 0);
/* Variables that depends on compile options */ /* Variables that depends on compile options */
#ifndef DBUG_OFF #ifndef DBUG_OFF
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace", default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
......
...@@ -831,17 +831,12 @@ bool Protocol_simple::store(TIME *tm) ...@@ -831,17 +831,12 @@ bool Protocol_simple::store(TIME *tm)
field_pos++; field_pos++;
#endif #endif
char buff[40]; char buff[40];
uint length; String tmp((char*) buff,sizeof(buff),&my_charset_bin);
length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d", DATETIME_FORMAT *tmp_format= (&t_datetime_frm
(int) tm->year, (current_thd, DATETIME_FORMAT_TYPE).datetime_format);
(int) tm->month, make_datetime(&tmp, tm, 1, tm->second_part,
(int) tm->day, tmp_format->format, tmp_format->format_length, 1);
(int) tm->hour, return net_store_data((char*) tmp.ptr(), tmp.length());
(int) tm->minute,
(int) tm->second));
if (tm->second_part)
length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part));
return net_store_data((char*) buff, length);
} }
...@@ -853,12 +848,12 @@ bool Protocol_simple::store_date(TIME *tm) ...@@ -853,12 +848,12 @@ bool Protocol_simple::store_date(TIME *tm)
field_pos++; field_pos++;
#endif #endif
char buff[40]; char buff[40];
uint length; String tmp((char*) buff,sizeof(buff),&my_charset_bin);
length= my_sprintf(buff,(buff, "%04d-%02d-%02d", DATETIME_FORMAT *tmp_format= (&t_datetime_frm
(int) tm->year, (current_thd, DATE_FORMAT_TYPE).datetime_format);
(int) tm->month, make_datetime(&tmp, tm, 1, 0,
(int) tm->day)); tmp_format->format, tmp_format->format_length, 1);
return net_store_data((char*) buff, length); return net_store_data((char*) tmp.ptr(), tmp.length());
} }
...@@ -876,16 +871,14 @@ bool Protocol_simple::store_time(TIME *tm) ...@@ -876,16 +871,14 @@ bool Protocol_simple::store_time(TIME *tm)
field_pos++; field_pos++;
#endif #endif
char buff[40]; char buff[40];
uint length; String tmp((char*) buff,sizeof(buff),&my_charset_bin);
DATETIME_FORMAT *tmp_format= (&t_datetime_frm
(current_thd, TIME_FORMAT_TYPE).datetime_format);
uint day= (tm->year || tm->month) ? 0 : tm->day; uint day= (tm->year || tm->month) ? 0 : tm->day;
length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d", tm->hour= (long) day*24L+(long) tm->hour;
tm->neg ? "-" : "", make_datetime(&tmp, tm, 0, tm->second_part,
(long) day*24L+(long) tm->hour, tmp_format->format, tmp_format->format_length, 1);
(int) tm->minute, return net_store_data((char*) tmp.ptr(), tmp.length());
(int) tm->second));
if (tm->second_part)
length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part));
return net_store_data((char*) buff, length);
} }
......
...@@ -383,6 +383,9 @@ sys_var *sys_variables[]= ...@@ -383,6 +383,9 @@ sys_var *sys_variables[]=
&sys_collation_connection, &sys_collation_connection,
&sys_concurrent_insert, &sys_concurrent_insert,
&sys_connect_timeout, &sys_connect_timeout,
&g_datetime_frm(DATE_FORMAT_TYPE),
&g_datetime_frm(DATETIME_FORMAT_TYPE),
&g_datetime_frm(TIME_FORMAT_TYPE),
&sys_default_week_format, &sys_default_week_format,
&sys_delay_key_write, &sys_delay_key_write,
&sys_delayed_insert_limit, &sys_delayed_insert_limit,
...@@ -512,6 +515,8 @@ struct show_var_st init_vars[]= { ...@@ -512,6 +515,8 @@ struct show_var_st init_vars[]= {
{sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
{sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
{"datadir", mysql_real_data_home, SHOW_CHAR}, {"datadir", mysql_real_data_home, SHOW_CHAR},
{"date_format", (char*) &g_datetime_frm(DATE_FORMAT_TYPE), SHOW_SYS},
{"datetime_format", (char*) &g_datetime_frm(DATETIME_FORMAT_TYPE), SHOW_SYS},
{"default_week_format", (char*) &sys_default_week_format, SHOW_SYS}, {"default_week_format", (char*) &sys_default_week_format, SHOW_SYS},
{sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS}, {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS},
{sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS}, {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS},
...@@ -661,6 +666,7 @@ struct show_var_st init_vars[]= { ...@@ -661,6 +666,7 @@ struct show_var_st init_vars[]= {
#endif #endif
{"thread_stack", (char*) &thread_stack, SHOW_LONG}, {"thread_stack", (char*) &thread_stack, SHOW_LONG},
{sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS}, {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
{"time_format", (char*) &g_datetime_frm(TIME_FORMAT_TYPE), SHOW_SYS},
#ifdef HAVE_TZNAME #ifdef HAVE_TZNAME
{"timezone", time_zone, SHOW_CHAR}, {"timezone", time_zone, SHOW_CHAR},
#endif #endif
...@@ -671,9 +677,75 @@ struct show_var_st init_vars[]= { ...@@ -671,9 +677,75 @@ struct show_var_st init_vars[]= {
{NullS, NullS, SHOW_LONG} {NullS, NullS, SHOW_LONG}
}; };
/* /*
Functions to check and update variables Functions to check and update variables
*/ */
char *update_datetime_format(THD *thd, enum enum_var_type type,
enum datetime_format_types format_type,
DATETIME_FORMAT *tmp_format)
{
char *old_value;
if (type == OPT_GLOBAL)
{
pthread_mutex_lock(&LOCK_global_system_variables);
old_value= g_datetime_frm(format_type).datetime_format.format;
g_datetime_frm(format_type).datetime_format= *tmp_format;
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
{
old_value= t_datetime_frm(thd,format_type).datetime_format.format;
t_datetime_frm(thd, format_type).datetime_format= *tmp_format;
}
return old_value;
}
bool sys_var_datetime_format::update(THD *thd, set_var *var)
{
DATETIME_FORMAT tmp_format;
char *old_value;
uint new_length;
if ((new_length= var->value->str_value.length()))
{
if (!make_format(&tmp_format, format_type,
var->value->str_value.ptr(),
new_length, 1))
return 1;
}
old_value= update_datetime_format(thd, var->type, format_type, &tmp_format);
my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
return 0;
}
byte *sys_var_datetime_format::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
if (type == OPT_GLOBAL)
return (byte*) g_datetime_frm(format_type).datetime_format.format;
return (byte*) t_datetime_frm(thd, format_type).datetime_format.format;
}
void sys_var_datetime_format::set_default(THD *thd, enum_var_type type)
{
DATETIME_FORMAT tmp_format;
char *old_value;
uint new_length;
if ((new_length= strlen(opt_datetime_formats[format_type])))
{
if (!make_format(&tmp_format, format_type,
opt_datetime_formats[format_type],
new_length, 1))
return;
}
old_value= update_datetime_format(thd, type, format_type, &tmp_format);
my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
}
/* /*
The following 3 functions need to be changed in 4.1 when we allow The following 3 functions need to be changed in 4.1 when we allow
......
...@@ -49,6 +49,8 @@ class sys_var ...@@ -49,6 +49,8 @@ class sys_var
const char *name; const char *name;
sys_after_update_func after_update; sys_after_update_func after_update;
sys_var()
{}
sys_var(const char *name_arg) :name(name_arg),after_update(0) sys_var(const char *name_arg) :name(name_arg),after_update(0)
{} {}
sys_var(const char *name_arg,sys_after_update_func func) sys_var(const char *name_arg,sys_after_update_func func)
...@@ -188,6 +190,9 @@ class sys_var_enum :public sys_var ...@@ -188,6 +190,9 @@ class sys_var_enum :public sys_var
class sys_var_thd :public sys_var class sys_var_thd :public sys_var
{ {
public: public:
sys_var_thd()
:sys_var()
{}
sys_var_thd(const char *name_arg) sys_var_thd(const char *name_arg)
:sys_var(name_arg) :sys_var(name_arg)
{} {}
...@@ -538,6 +543,51 @@ class sys_var_key_buffer_size :public sys_var ...@@ -538,6 +543,51 @@ class sys_var_key_buffer_size :public sys_var
}; };
class sys_var_datetime_format :public sys_var_thd
{
public:
enum datetime_format_types format_type;
DATETIME_FORMAT datetime_format;
sys_var_datetime_format(): sys_var_thd()
{}
void clean()
{
my_free(datetime_format.format, MYF(MY_ALLOW_ZERO_PTR));
datetime_format.format=0;
}
/*
It's for copying of global_system_variables structure
in THD constructor.
*/
inline sys_var_datetime_format& operator= (sys_var_datetime_format& s)
{
if (&s != this)
{
name= s.name; name_length= s.name_length;
datetime_format= s.datetime_format;
datetime_format.format= (my_strdup_with_length
(s.datetime_format.format,
s.datetime_format.
format_length, MYF(0)));
format_type= s.format_type;
}
return *this;
}
SHOW_TYPE type() { return SHOW_CHAR; }
bool check_update_type(Item_result type)
{
return type != STRING_RESULT; /* Only accept strings */
}
bool check_default(enum_var_type type) { return 0; }
bool update(THD *thd, set_var *var);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
void set_default(THD *thd, enum_var_type type);
};
/* Variable that you can only read from */ /* Variable that you can only read from */
class sys_var_readonly: public sys_var class sys_var_readonly: public sys_var
......
...@@ -274,6 +274,9 @@ void THD::cleanup(void) ...@@ -274,6 +274,9 @@ void THD::cleanup(void)
close_thread_tables(this); close_thread_tables(this);
} }
close_temporary_tables(this); close_temporary_tables(this);
variables.datetime_formats[DATE_FORMAT_TYPE].clean();
variables.datetime_formats[TIME_FORMAT_TYPE].clean();
variables.datetime_formats[DATETIME_FORMAT_TYPE].clean();
delete_dynamic(&user_var_events); delete_dynamic(&user_var_events);
hash_free(&user_vars); hash_free(&user_vars);
if (global_read_lock) if (global_read_lock)
......
...@@ -406,6 +406,7 @@ struct system_variables ...@@ -406,6 +406,7 @@ struct system_variables
CHARSET_INFO *character_set_client; CHARSET_INFO *character_set_client;
CHARSET_INFO *character_set_results; CHARSET_INFO *character_set_results;
CHARSET_INFO *collation_connection; CHARSET_INFO *collation_connection;
sys_var_datetime_format datetime_formats[3];
}; };
void free_tmp_table(THD *thd, TABLE *entry); void free_tmp_table(THD *thd, TABLE *entry);
......
...@@ -79,6 +79,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) ...@@ -79,6 +79,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B)
CHARSET_INFO *charset; CHARSET_INFO *charset;
thr_lock_type lock_type; thr_lock_type lock_type;
interval_type interval; interval_type interval;
datetime_format_types datetime_format_type;
st_select_lex *select_lex; st_select_lex *select_lex;
chooser_compare_func_creator boolfunc2creator; chooser_compare_func_creator boolfunc2creator;
} }
...@@ -477,6 +478,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -477,6 +478,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token GEOMETRYCOLLECTION %token GEOMETRYCOLLECTION
%token GROUP_CONCAT_SYM %token GROUP_CONCAT_SYM
%token GROUP_UNIQUE_USERS %token GROUP_UNIQUE_USERS
%token GET_FORMAT
%token HOUR_MICROSECOND_SYM %token HOUR_MICROSECOND_SYM
%token HOUR_MINUTE_SYM %token HOUR_MINUTE_SYM
%token HOUR_SECOND_SYM %token HOUR_SECOND_SYM
...@@ -639,6 +641,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -639,6 +641,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
UDF_CHAR_FUNC UDF_FLOAT_FUNC UDF_INT_FUNC UDF_CHAR_FUNC UDF_FLOAT_FUNC UDF_INT_FUNC
UDA_CHAR_SUM UDA_FLOAT_SUM UDA_INT_SUM UDA_CHAR_SUM UDA_FLOAT_SUM UDA_INT_SUM
%type <datetime_format_type> datetime_format_type;
%type <interval> interval %type <interval> interval
%type <db_type> table_types %type <db_type> table_types
...@@ -2529,6 +2532,8 @@ simple_expr: ...@@ -2529,6 +2532,8 @@ simple_expr:
{ $$= new Item_func_spatial_collection(* $3, { $$= new Item_func_spatial_collection(* $3,
Geometry::wkbGeometryCollection, Geometry::wkbGeometryCollection,
Geometry::wkbPoint); } Geometry::wkbPoint); }
| GET_FORMAT '(' datetime_format_type ',' expr ')'
{ $$= new Item_func_get_format($3, $5); }
| HOUR_SYM '(' expr ')' | HOUR_SYM '(' expr ')'
{ $$= new Item_func_hour($3); } { $$= new Item_func_hour($3); }
| IF '(' expr ',' expr ',' expr ')' | IF '(' expr ',' expr ',' expr ')'
...@@ -3133,6 +3138,11 @@ interval: ...@@ -3133,6 +3138,11 @@ interval:
| YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; }
| YEAR_SYM { $$=INTERVAL_YEAR; }; | YEAR_SYM { $$=INTERVAL_YEAR; };
datetime_format_type:
DATE_SYM {$$=DATE_FORMAT_TYPE;}
| TIME_SYM {$$=TIME_FORMAT_TYPE;}
| DATETIME {$$=DATETIME_FORMAT_TYPE;};
table_alias: table_alias:
/* empty */ /* empty */
| AS | AS
...@@ -4479,6 +4489,7 @@ keyword: ...@@ -4479,6 +4489,7 @@ keyword:
| FLUSH_SYM {} | FLUSH_SYM {}
| GEOMETRY_SYM {} | GEOMETRY_SYM {}
| GEOMETRYCOLLECTION {} | GEOMETRYCOLLECTION {}
| GET_FORMAT {}
| GRANTS {} | GRANTS {}
| GLOBAL_SYM {} | GLOBAL_SYM {}
| HANDLER_SYM {} | HANDLER_SYM {}
......
...@@ -24,6 +24,11 @@ typedef struct st_date_format { /* How to print date */ ...@@ -24,6 +24,11 @@ typedef struct st_date_format { /* How to print date */
uint pos[6]; /* Positions to YY.MM.DD HH:MM:SS */ uint pos[6]; /* Positions to YY.MM.DD HH:MM:SS */
} DATE_FORMAT; } DATE_FORMAT;
typedef struct st_datetime_format {
byte dt_pos[8];
char *format;
uint format_length;
} DATETIME_FORMAT;
typedef struct st_keyfile_info { /* used with ha_info() */ typedef struct st_keyfile_info { /* used with ha_info() */
byte ref[MAX_REFLENGTH]; /* Pointer to current row */ byte ref[MAX_REFLENGTH]; /* Pointer to current row */
...@@ -110,8 +115,8 @@ typedef struct st_read_record { /* Parameter to read_record */ ...@@ -110,8 +115,8 @@ typedef struct st_read_record { /* Parameter to read_record */
bool print_error, ignore_not_found_rows; bool print_error, ignore_not_found_rows;
} READ_RECORD; } READ_RECORD;
enum timestamp_type { TIMESTAMP_NONE, TIMESTAMP_DATE, TIMESTAMP_FULL, enum timestamp_type { TIMESTAMP_NONE, WRONG_TIMESTAMP_FULL, TIMESTAMP_DATE, TIMESTAMP_FULL,
TIMESTAMP_TIME }; TIMESTAMP_TIME};
typedef struct st_time { typedef struct st_time {
uint year,month,day,hour,minute,second; uint year,month,day,hour,minute,second;
......
This diff is collapsed.
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