Task #835: additional changes fot str_to_date
This commit is contained in:
parent
54167da4b0
commit
df0ede69fc
@ -308,4 +308,5 @@
|
||||
#define ER_FEATURE_DISABLED 1289
|
||||
#define ER_OPTION_PREVENTS_STATEMENT 1290
|
||||
#define ER_DUPLICATED_VALUE_IN_TYPE 1291
|
||||
#define ER_ERROR_MESSAGES 292
|
||||
#define ER_TRUNCATED_WRONG_VALUE 1292
|
||||
#define ER_ERROR_MESSAGES 293
|
||||
|
@ -78,11 +78,11 @@ select str_to_date(concat('15-01-2001',' 2:59:58.999'),
|
||||
concat('%d-%m-%Y',' ','%H:%i:%s.%f'));
|
||||
str_to_date(concat('15-01-2001',' 2:59:58.999'),
|
||||
concat('%d-%m-%Y',' ','%H:%i:%s.%f'))
|
||||
2001-01-15 02:59:58.000999
|
||||
2001-01-15 02:59:58.999000
|
||||
create table t1 (date char(30), format char(30) not null);
|
||||
insert into t1 values
|
||||
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
|
||||
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'),
|
||||
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
|
||||
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
|
||||
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
|
||||
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
|
||||
@ -106,16 +106,16 @@ insert into t1 values
|
||||
select date,format,str_to_date(date, format) as str_to_date from t1;
|
||||
date format str_to_date
|
||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
|
||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
|
||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
||||
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
||||
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
||||
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
|
||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
|
||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
||||
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
||||
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
||||
@ -130,16 +130,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
|
||||
select date,format,concat('',str_to_date(date, format)) as con from t1;
|
||||
date format con
|
||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
|
||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
|
||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
||||
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
||||
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
||||
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
|
||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
|
||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
||||
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
||||
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
||||
@ -154,16 +154,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
|
||||
select date,format,cast(str_to_date(date, format) as datetime) as datetime from t1;
|
||||
date format datetime
|
||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 10:11:12
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02 08:11:02
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02 08:11:02
|
||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02 22:11:12
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.012345
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.012345
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.012345
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 01:11:12.123450
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450
|
||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12
|
||||
10:20:10 %H:%i:%s 0000-00-00 10:20:10
|
||||
10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10
|
||||
10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10
|
||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.000044
|
||||
10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000
|
||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58
|
||||
15 September 2001 %d %M %Y 2001-09-15 00:00:00
|
||||
15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00
|
||||
@ -178,7 +178,7 @@ Thursday 53 1998 %W %u %Y 1998-12-31 00:00:00
|
||||
select date,format,DATE(str_to_date(date, format)) as date2 from t1;
|
||||
date format date2
|
||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 2003-01-02
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 2003-01-02
|
||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 2003-01-02
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 2003-01-02
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02
|
||||
@ -202,16 +202,16 @@ Thursday 53 1998 %W %u %Y 1998-12-31
|
||||
select date,format,TIME(str_to_date(date, format)) as time from t1;
|
||||
date format time
|
||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
|
||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450
|
||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
|
||||
10:20:10 %H:%i:%s 10:20:10
|
||||
10:20:10 %h:%i:%s.%f 10:20:10
|
||||
10:20:10AM %h:%i:%s%p 10:20:10
|
||||
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044
|
||||
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000
|
||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
|
||||
15 September 2001 %d %M %Y 00:00:00
|
||||
15 SEPTEMB 2001 %d %M %Y 00:00:00
|
||||
@ -226,16 +226,16 @@ Thursday 53 1998 %W %u %Y 00:00:00
|
||||
select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1;
|
||||
date format time2
|
||||
2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S 08:11:02
|
||||
03-01-02 8:11:2.123456 %y-%m-%d %H:%i:%S.%# 08:11:02
|
||||
2003-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 22:11:12
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.012345
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.012345
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.012345
|
||||
2003-01-02 01:11:12.12345AM %Y-%m-%d %h:%i:%S.%f%p 01:11:12.123450
|
||||
2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450
|
||||
2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450
|
||||
2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12
|
||||
10:20:10 %H:%i:%s 10:20:10
|
||||
10:20:10 %h:%i:%s.%f 10:20:10
|
||||
10:20:10AM %h:%i:%s%p 10:20:10
|
||||
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.000044
|
||||
10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000
|
||||
15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58
|
||||
15 September 2001 %d %M %Y 00:00:00
|
||||
15 SEPTEMB 2001 %d %M %Y 00:00:00
|
||||
@ -302,11 +302,15 @@ date format str_to_date
|
||||
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
|
||||
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
|
||||
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
|
||||
Warnings:
|
||||
Note 1292 Truncated wrong string value: '10:20:10AM'
|
||||
select date,format,concat(str_to_date(date, format),'') as con from t1;
|
||||
date format con
|
||||
10:20:10AM %h:%i:%s 0000-00-00 10:20:10
|
||||
2003-01-02 10:11:12 %Y-%m-%d %h:%i:%S 2003-01-02 10:11:12
|
||||
03-01-02 10:11:12 PM %Y-%m-%d %h:%i:%S %p 0003-01-02 22:11:12
|
||||
Warnings:
|
||||
Note 1292 Truncated wrong string value: '10:20:10AM'
|
||||
drop table t1;
|
||||
select get_format(DATE, 'USA') as a;
|
||||
a
|
||||
@ -335,3 +339,56 @@ date_format(d,"%d")
|
||||
14
|
||||
14
|
||||
drop table t1;
|
||||
select str_to_date("2003-....01ABCD-02 10:11:12.0012", "%Y-%.%m%@-%d %H:%i:%S.%f") as a;
|
||||
a
|
||||
2003-01-02 10:11:12.001200
|
||||
create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||
str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2,
|
||||
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
|
||||
describe t1;
|
||||
Field Type Null Key Default Extra
|
||||
f1 datetime YES NULL
|
||||
f2 time YES NULL
|
||||
f3 date YES NULL
|
||||
f4 date YES NULL
|
||||
f5 time YES NULL
|
||||
select * from t1;
|
||||
f1 f2 f3 f4 f5
|
||||
2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 58:00:00
|
||||
drop table t1;
|
||||
create table t1 select "02 10" as a, "%d %H" as b;
|
||||
select str_to_date(a,b) from t1;
|
||||
str_to_date(a,b)
|
||||
0000-00-02 10:00:00
|
||||
create table t2 select str_to_date(a,b) from t1;
|
||||
describe t2;
|
||||
Field Type Null Key Default Extra
|
||||
str_to_date(a,b) char(29) YES NULL
|
||||
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
|
||||
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||
str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
|
||||
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
|
||||
str_to_date("02 10", "%d %f") as f6;
|
||||
f1 f2 f3 f4 f5 f6
|
||||
2003-01-02 10:11:12.001200 2003-01-02 10:11:12 2003-01-02 58:11:12 58:11:12 48:00:00.100000
|
||||
Warnings:
|
||||
Note 1292 Truncated wrong datetime value: '2003-01-02 10:11:12.0012'
|
||||
drop table t1, t2;
|
||||
select str_to_date("2003-01-02 10:11:12.0012ABCD", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||
addtime("-01:01:01.01 GGG", "-23:59:59.1") as f2,
|
||||
microsecond("1997-12-31 23:59:59.01XXXX") as f3;
|
||||
f1 f2 f3
|
||||
2003-01-02 10:11:12.001200 -25:01:00.110000 10000
|
||||
Warnings:
|
||||
Note 1292 Truncated wrong datetime value: '2003-01-02 10:11:12.0012ABCD'
|
||||
Note 1292 Truncated wrong time value: '-01:01:01.01 GG'
|
||||
Note 1292 Truncated wrong datetime value: '1997-12-31 23:59:59.01XXXX'
|
||||
select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
|
||||
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
|
||||
f1 f2
|
||||
2003-04-05 2003-04-05 10:11:12.101010
|
||||
Warnings:
|
||||
Note 1292 Truncated wrong date value: '2003-04-05 g'
|
||||
Note 1292 Truncated wrong datetime value: '2003-04-05 10:11:12.101010234567'
|
||||
|
@ -198,3 +198,18 @@ NULL NULL
|
||||
NULL NULL
|
||||
00:00:00 -24:00:00
|
||||
drop table t1, test;
|
||||
select addtime("-01:01:01.01", "-23:59:59.1") as a;
|
||||
a
|
||||
-25:01:00.110000
|
||||
select microsecond("1997-12-31 23:59:59.01") as a;
|
||||
a
|
||||
10000
|
||||
select microsecond(19971231235959.01) as a;
|
||||
a
|
||||
10000
|
||||
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
|
||||
a
|
||||
1997-12-31 00:00:10.090000
|
||||
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f");
|
||||
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f")
|
||||
2003-01-02 10:11:12.001200
|
||||
|
@ -506,17 +506,32 @@ last_day('2001-01-01 01:01:01') as f5, last_day(NULL),
|
||||
last_day('2001-02-12');
|
||||
f1 f2 f3 f4 f5 last_day(NULL) last_day('2001-02-12')
|
||||
2000-02-29 2002-12-31 NULL 2003-04-30 2001-01-31 NULL 2001-02-28
|
||||
create table t1 select last_day('2000-02-05') as a;
|
||||
create table t1 select last_day('2000-02-05') as a,
|
||||
from_days(to_days("960101")) as b;
|
||||
describe t1;
|
||||
Field Type Null Key Default Extra
|
||||
a date 0000-00-00
|
||||
b date YES NULL
|
||||
select * from t1;
|
||||
a
|
||||
2000-02-29
|
||||
a b
|
||||
2000-02-29 1996-01-01
|
||||
drop table t1;
|
||||
select last_day('2000-02-05');
|
||||
last_day('2000-02-05')
|
||||
2000-02-29
|
||||
select last_day('2000-02-05') as a,
|
||||
from_days(to_days("960101")) as b;
|
||||
a b
|
||||
2000-02-29 1996-01-01
|
||||
select date_add(last_day("1997-12-1"), INTERVAL 1 DAY);
|
||||
date_add(last_day("1997-12-1"), INTERVAL 1 DAY)
|
||||
1998-01-01
|
||||
select length(last_day("1997-12-1"));
|
||||
length(last_day("1997-12-1"))
|
||||
10
|
||||
select last_day("1997-12-1")+0;
|
||||
last_day("1997-12-1")+0
|
||||
19971231
|
||||
select last_day("1997-12-1")+0.0;
|
||||
last_day("1997-12-1")+0.0
|
||||
19971231.0
|
||||
select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0;
|
||||
strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0
|
||||
1
|
||||
|
@ -25,9 +25,11 @@ t
|
||||
36:30:31
|
||||
insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a");
|
||||
Warnings:
|
||||
Note 1292 Truncated wrong time value: '10.22.22'
|
||||
Warning 1264 Data truncated, out of range for column 't' at row 2
|
||||
Warning 1264 Data truncated, out of range for column 't' at row 3
|
||||
Warning 1264 Data truncated, out of range for column 't' at row 4
|
||||
Note 1292 Truncated wrong time value: '12.45a'
|
||||
select * from t1;
|
||||
t
|
||||
10:22:33
|
||||
|
@ -124,7 +124,7 @@ select str_to_date(concat('15-01-2001',' 2:59:58.999'),
|
||||
create table t1 (date char(30), format char(30) not null);
|
||||
insert into t1 values
|
||||
('2003-01-02 10:11:12', '%Y-%m-%d %H:%i:%S'),
|
||||
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S'),
|
||||
('03-01-02 8:11:2.123456', '%y-%m-%d %H:%i:%S.%#'),
|
||||
('2003-01-02 10:11:12 PM', '%Y-%m-%d %h:%i:%S %p'),
|
||||
('2003-01-02 01:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f%p'),
|
||||
('2003-01-02 02:11:12.12345AM', '%Y-%m-%d %h:%i:%S.%f %p'),
|
||||
@ -209,3 +209,32 @@ create table t1 (d date);
|
||||
insert into t1 values ('2004-07-14'),('2005-07-14');
|
||||
select date_format(d,"%d") from t1 order by 1;
|
||||
drop table t1;
|
||||
|
||||
select str_to_date("2003-....01ABCD-02 10:11:12.0012", "%Y-%.%m%@-%d %H:%i:%S.%f") as a;
|
||||
|
||||
|
||||
create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||
str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2,
|
||||
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||
str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5;
|
||||
describe t1;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
create table t1 select "02 10" as a, "%d %H" as b;
|
||||
select str_to_date(a,b) from t1;
|
||||
create table t2 select str_to_date(a,b) from t1;
|
||||
describe t2;
|
||||
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
|
||||
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
|
||||
str_to_date("02 10:11:12", "%d %H:%i:%S.%f") as f4,
|
||||
str_to_date("02 10:11:12", "%d %H:%i:%S") as f5,
|
||||
str_to_date("02 10", "%d %f") as f6;
|
||||
drop table t1, t2;
|
||||
select str_to_date("2003-01-02 10:11:12.0012ABCD", "%Y-%m-%d %H:%i:%S.%f") as f1,
|
||||
addtime("-01:01:01.01 GGG", "-23:59:59.1") as f2,
|
||||
microsecond("1997-12-31 23:59:59.01XXXX") as f3;
|
||||
|
||||
select str_to_date("2003-04-05 g", "%Y-%m-%d") as f1,
|
||||
str_to_date("2003-04-05 10:11:12.101010234567", "%Y-%m-%d %H:%i:%S.%f") as f2;
|
||||
|
@ -97,3 +97,9 @@ SELECT ADDTIME(t1,t2) As ttt, ADDTIME(t2, t3) As qqq from test;
|
||||
SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
|
||||
|
||||
drop table t1, test;
|
||||
|
||||
select addtime("-01:01:01.01", "-23:59:59.1") as a;
|
||||
select microsecond("1997-12-31 23:59:59.01") as a;
|
||||
select microsecond(19971231235959.01) as a;
|
||||
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
|
||||
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f");
|
||||
|
@ -249,12 +249,18 @@ select last_day('2000-02-05') as f1, last_day('2002-12-31') as f2,
|
||||
last_day('2001-01-01 01:01:01') as f5, last_day(NULL),
|
||||
last_day('2001-02-12');
|
||||
|
||||
create table t1 select last_day('2000-02-05') as a;
|
||||
create table t1 select last_day('2000-02-05') as a,
|
||||
from_days(to_days("960101")) as b;
|
||||
describe t1;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
select last_day('2000-02-05');
|
||||
select last_day('2000-02-05') as a,
|
||||
from_days(to_days("960101")) as b;
|
||||
|
||||
select date_add(last_day("1997-12-1"), INTERVAL 1 DAY);
|
||||
select length(last_day("1997-12-1"));
|
||||
select last_day("1997-12-1")+0;
|
||||
select last_day("1997-12-1")+0.0;
|
||||
|
||||
# Test SAPDB UTC_% functions. This part is TZ dependant (It is supposed that
|
||||
# TZ variable set to GMT-3
|
||||
|
@ -48,11 +48,6 @@ TYPELIB day_names_typelib=
|
||||
{ array_elements(day_names)-1,"", day_names};
|
||||
|
||||
|
||||
enum date_time_format_types
|
||||
{
|
||||
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
|
||||
};
|
||||
|
||||
/*
|
||||
OPTIMIZATION TODO:
|
||||
- Replace the switch with a function that should be called for each
|
||||
@ -128,6 +123,9 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
|
||||
val String to decode
|
||||
length Length of string
|
||||
l_time Store result here
|
||||
cached_timestamp_type
|
||||
It uses to get an appropriate warning
|
||||
in the case when the value is truncated.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
@ -135,7 +133,8 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
|
||||
*/
|
||||
|
||||
static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
const char *val, uint length, TIME *l_time)
|
||||
const char *val, uint length, TIME *l_time,
|
||||
timestamp_type cached_timestamp_type)
|
||||
{
|
||||
int weekday= 0, yearday= 0, daypart= 0;
|
||||
int week_number= -1;
|
||||
@ -143,9 +142,11 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
int error= 0;
|
||||
bool usa_time= 0;
|
||||
bool sunday_first= 0;
|
||||
int frac_part;
|
||||
const char *val_begin= val;
|
||||
const char *val_end= val + length;
|
||||
const char *ptr= format->format.str;
|
||||
const char *end= ptr+ format->format.length;
|
||||
const char *end= ptr + format->format.length;
|
||||
DBUG_ENTER("extract_date_time");
|
||||
|
||||
bzero((char*) l_time, sizeof(*l_time));
|
||||
@ -235,7 +236,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
/* Second part */
|
||||
case 'f':
|
||||
tmp= (char*) val_end;
|
||||
if (tmp - val > 6)
|
||||
tmp= (char*) val + 6;
|
||||
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
|
||||
frac_part= 6 - (tmp - val);
|
||||
if (frac_part > 0)
|
||||
l_time->second_part*= (ulong) log_10_int[frac_part];
|
||||
val= tmp;
|
||||
break;
|
||||
|
||||
@ -251,6 +257,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
(const uchar *) val, 2,
|
||||
(const uchar *) "AM", 2))
|
||||
goto err;
|
||||
val+= 2;
|
||||
break;
|
||||
|
||||
/* Exotic things */
|
||||
@ -281,6 +288,18 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
val= tmp;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
while (my_ispunct(cs, *val) && val != val_end)
|
||||
val++;
|
||||
break;
|
||||
case '@':
|
||||
while (my_isalpha(cs, *val) && val != val_end)
|
||||
val++;
|
||||
break;
|
||||
case '#':
|
||||
while (my_isdigit(cs, *val) && val != val_end)
|
||||
val++;
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
@ -348,6 +367,18 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
l_time->minute > 59 || l_time->second > 59)
|
||||
goto err;
|
||||
|
||||
if (val != val_end)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!my_isspace(&my_charset_latin1,*val))
|
||||
{
|
||||
make_truncated_value_warning(current_thd, val_begin, length,
|
||||
cached_timestamp_type);
|
||||
break;
|
||||
}
|
||||
} while (++val != val_end);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
@ -584,16 +615,27 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
|
||||
|
||||
|
||||
/*
|
||||
** Get a array of positive numbers from a string object.
|
||||
** Each number is separated by 1 non digit character
|
||||
** Return error if there is too many numbers.
|
||||
** If there is too few numbers, assume that the numbers are left out
|
||||
** from the high end. This allows one to give:
|
||||
** DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
||||
Get a array of positive numbers from a string object.
|
||||
Each number is separated by 1 non digit character
|
||||
Return error if there is too many numbers.
|
||||
If there is too few numbers, assume that the numbers are left out
|
||||
from the high end. This allows one to give:
|
||||
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
||||
|
||||
SYNOPSIS
|
||||
str: string value
|
||||
length: length of str
|
||||
cs: charset of str
|
||||
values: array of results
|
||||
count: count of elements in result array
|
||||
transform_msec: if value is true we suppose
|
||||
that the last part of string value is microseconds
|
||||
and we should transform value to six digit value.
|
||||
For example, '1.1' -> '1.100000'
|
||||
*/
|
||||
|
||||
bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||
uint count, long *values)
|
||||
uint count, long *values, bool transform_msec)
|
||||
{
|
||||
const char *end=str+length;
|
||||
uint i;
|
||||
@ -603,8 +645,15 @@ bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||
for (i=0 ; i < count ; i++)
|
||||
{
|
||||
long value;
|
||||
const char *start= str;
|
||||
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
|
||||
value=value*10L + (long) (*str - '0');
|
||||
if (transform_msec && i == count - 1) // microseconds always last
|
||||
{
|
||||
long msec_length= 6 - (str - start);
|
||||
if (msec_length > 0)
|
||||
value*= (long) log_10_int[msec_length];
|
||||
}
|
||||
values[i]= value;
|
||||
while (str != end && !my_isdigit(cs,*str))
|
||||
str++;
|
||||
@ -925,19 +974,19 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
||||
interval->second=value;
|
||||
break;
|
||||
case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
|
||||
if (get_interval_info(str,length,cs,2,array))
|
||||
if (get_interval_info(str,length,cs,2,array,0))
|
||||
return (1);
|
||||
interval->year=array[0];
|
||||
interval->month=array[1];
|
||||
break;
|
||||
case INTERVAL_DAY_HOUR:
|
||||
if (get_interval_info(str,length,cs,2,array))
|
||||
if (get_interval_info(str,length,cs,2,array,0))
|
||||
return (1);
|
||||
interval->day=array[0];
|
||||
interval->hour=array[1];
|
||||
break;
|
||||
case INTERVAL_DAY_MICROSECOND:
|
||||
if (get_interval_info(str,length,cs,5,array))
|
||||
if (get_interval_info(str,length,cs,5,array,1))
|
||||
return (1);
|
||||
interval->day=array[0];
|
||||
interval->hour=array[1];
|
||||
@ -946,14 +995,14 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
||||
interval->second_part=array[4];
|
||||
break;
|
||||
case INTERVAL_DAY_MINUTE:
|
||||
if (get_interval_info(str,length,cs,3,array))
|
||||
if (get_interval_info(str,length,cs,3,array,0))
|
||||
return (1);
|
||||
interval->day=array[0];
|
||||
interval->hour=array[1];
|
||||
interval->minute=array[2];
|
||||
break;
|
||||
case INTERVAL_DAY_SECOND:
|
||||
if (get_interval_info(str,length,cs,4,array))
|
||||
if (get_interval_info(str,length,cs,4,array,0))
|
||||
return (1);
|
||||
interval->day=array[0];
|
||||
interval->hour=array[1];
|
||||
@ -961,7 +1010,7 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
||||
interval->second=array[3];
|
||||
break;
|
||||
case INTERVAL_HOUR_MICROSECOND:
|
||||
if (get_interval_info(str,length,cs,4,array))
|
||||
if (get_interval_info(str,length,cs,4,array,1))
|
||||
return (1);
|
||||
interval->hour=array[0];
|
||||
interval->minute=array[1];
|
||||
@ -969,33 +1018,33 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
||||
interval->second_part=array[3];
|
||||
break;
|
||||
case INTERVAL_HOUR_MINUTE:
|
||||
if (get_interval_info(str,length,cs,2,array))
|
||||
if (get_interval_info(str,length,cs,2,array,0))
|
||||
return (1);
|
||||
interval->hour=array[0];
|
||||
interval->minute=array[1];
|
||||
break;
|
||||
case INTERVAL_HOUR_SECOND:
|
||||
if (get_interval_info(str,length,cs,3,array))
|
||||
if (get_interval_info(str,length,cs,3,array,0))
|
||||
return (1);
|
||||
interval->hour=array[0];
|
||||
interval->minute=array[1];
|
||||
interval->second=array[2];
|
||||
break;
|
||||
case INTERVAL_MINUTE_MICROSECOND:
|
||||
if (get_interval_info(str,length,cs,3,array))
|
||||
if (get_interval_info(str,length,cs,3,array,1))
|
||||
return (1);
|
||||
interval->minute=array[0];
|
||||
interval->second=array[1];
|
||||
interval->second_part=array[2];
|
||||
break;
|
||||
case INTERVAL_MINUTE_SECOND:
|
||||
if (get_interval_info(str,length,cs,2,array))
|
||||
if (get_interval_info(str,length,cs,2,array,0))
|
||||
return (1);
|
||||
interval->minute=array[0];
|
||||
interval->second=array[1];
|
||||
break;
|
||||
case INTERVAL_SECOND_MICROSECOND:
|
||||
if (get_interval_info(str,length,cs,2,array))
|
||||
if (get_interval_info(str,length,cs,2,array,1))
|
||||
return (1);
|
||||
interval->second=array[0];
|
||||
interval->second_part=array[1];
|
||||
@ -1008,22 +1057,13 @@ static bool get_interval_value(Item *args,interval_type int_type,
|
||||
String *Item_date::val_str(String *str)
|
||||
{
|
||||
TIME ltime;
|
||||
ulong value=(ulong) val_int();
|
||||
if (null_value)
|
||||
return (String*) 0;
|
||||
|
||||
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||
return (String *) 0;
|
||||
if (str->alloc(11))
|
||||
{
|
||||
null_value= 1;
|
||||
return (String *) 0;
|
||||
}
|
||||
|
||||
ltime.year= (value/10000L) % 10000;
|
||||
ltime.month= (value/100)%100;
|
||||
ltime.day= (value%100);
|
||||
ltime.neg= 0;
|
||||
ltime.time_type=TIMESTAMP_DATE;
|
||||
|
||||
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
|
||||
return str;
|
||||
}
|
||||
@ -1032,28 +1072,31 @@ String *Item_date::val_str(String *str)
|
||||
int Item_date::save_in_field(Field *field, bool no_conversions)
|
||||
{
|
||||
TIME ltime;
|
||||
timestamp_type t_type=TIMESTAMP_DATETIME;
|
||||
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||
{
|
||||
if (null_value)
|
||||
return set_field_to_null(field);
|
||||
t_type=TIMESTAMP_NONE; // Error
|
||||
}
|
||||
return set_field_to_null(field);
|
||||
field->set_notnull();
|
||||
field->store_time(<ime,t_type);
|
||||
field->store_time(<ime, TIMESTAMP_DATE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_from_days::val_int()
|
||||
longlong Item_date::val_int()
|
||||
{
|
||||
TIME ltime;
|
||||
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||
return 0;
|
||||
return (longlong) (ltime.year*10000L+ltime.month*100+ltime.day);
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date)
|
||||
{
|
||||
longlong value=args[0]->val_int();
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0; /* purecov: inspected */
|
||||
|
||||
uint year,month,day;
|
||||
get_date_from_daynr((long) value,&year,&month,&day);
|
||||
return (longlong) (year*10000L+month*100+day);
|
||||
return 1;
|
||||
get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day);
|
||||
ltime->time_type= TIMESTAMP_DATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1082,6 +1125,16 @@ void Item_func_curdate::fix_length_and_dec()
|
||||
ltime.time_type=TIMESTAMP_DATE;
|
||||
}
|
||||
|
||||
String *Item_func_curdate::val_str(String *str)
|
||||
{
|
||||
if (str->alloc(11))
|
||||
{
|
||||
null_value= 1;
|
||||
return (String *) 0;
|
||||
}
|
||||
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
bool Item_func_curdate::get_date(TIME *res,
|
||||
uint fuzzy_date __attribute__((unused)))
|
||||
@ -2311,6 +2364,103 @@ void Item_func_get_format::print(String *str)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
check_result_type(s, l) returns DATE/TIME type
|
||||
according to format string
|
||||
|
||||
s: DATE/TIME format string
|
||||
l: length of s
|
||||
Result: date_time_format_types value:
|
||||
DATE_TIME_MICROSECOND, DATE_TIME,
|
||||
TIME_MICROSECOND, TIME_ONLY
|
||||
|
||||
We don't process day format's characters('D', 'd', 'e')
|
||||
because day may be a member of all date/time types.
|
||||
If only day format's character and no time part present
|
||||
the result type is MYSQL_TYPE_DATE
|
||||
*/
|
||||
|
||||
date_time_format_types check_result_type(const char *format, uint length)
|
||||
{
|
||||
const char *time_part_frms= "HISThiklrs";
|
||||
const char *date_part_frms= "MUYWabcjmuyw";
|
||||
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
|
||||
|
||||
const char *val= format;
|
||||
const char *end= format + length;
|
||||
|
||||
for (; val != end && val != end; val++)
|
||||
{
|
||||
if (*val == '%' && val+1 != end)
|
||||
{
|
||||
val++;
|
||||
if ((frac_second_used= (*val == 'f')) ||
|
||||
(!time_part_used && strchr(time_part_frms, *val)))
|
||||
time_part_used= 1;
|
||||
else if (!date_part_used && strchr(date_part_frms, *val))
|
||||
date_part_used= 1;
|
||||
if (time_part_used && date_part_used && frac_second_used)
|
||||
return DATE_TIME_MICROSECOND;
|
||||
}
|
||||
}
|
||||
|
||||
if (time_part_used)
|
||||
{
|
||||
if (date_part_used)
|
||||
return DATE_TIME;
|
||||
if (frac_second_used)
|
||||
return TIME_MICROSECOND;
|
||||
return TIME_ONLY;
|
||||
}
|
||||
return DATE_ONLY;
|
||||
}
|
||||
|
||||
|
||||
Field *Item_func_str_to_date::tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
if (cached_field_type == MYSQL_TYPE_TIME)
|
||||
return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
|
||||
if (cached_field_type == MYSQL_TYPE_DATE)
|
||||
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
|
||||
if (cached_field_type == MYSQL_TYPE_DATETIME)
|
||||
return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
|
||||
return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin));
|
||||
}
|
||||
|
||||
|
||||
void Item_func_str_to_date::fix_length_and_dec()
|
||||
{
|
||||
char format_buff[64];
|
||||
String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format;
|
||||
maybe_null= 1;
|
||||
decimals=0;
|
||||
cached_field_type= MYSQL_TYPE_STRING;
|
||||
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
cached_timestamp_type= TIMESTAMP_NONE;
|
||||
if ((const_item= args[1]->const_item()))
|
||||
{
|
||||
format= args[1]->val_str(&format_str);
|
||||
cached_format_type= check_result_type(format->ptr(), format->length());
|
||||
switch (cached_format_type) {
|
||||
case DATE_ONLY:
|
||||
cached_timestamp_type= TIMESTAMP_DATE;
|
||||
cached_field_type= MYSQL_TYPE_DATE;
|
||||
max_length= MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
break;
|
||||
case TIME_ONLY:
|
||||
case TIME_MICROSECOND:
|
||||
cached_timestamp_type= TIMESTAMP_TIME;
|
||||
cached_field_type= MYSQL_TYPE_TIME;
|
||||
max_length= MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
break;
|
||||
default:
|
||||
cached_timestamp_type= TIMESTAMP_DATETIME;
|
||||
cached_field_type= MYSQL_TYPE_DATETIME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
|
||||
{
|
||||
DATE_TIME_FORMAT date_time_format;
|
||||
@ -2328,8 +2478,18 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
|
||||
date_time_format.format.str= (char*) format->ptr();
|
||||
date_time_format.format.length= format->length();
|
||||
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
|
||||
ltime))
|
||||
ltime, cached_timestamp_type))
|
||||
goto null_date;
|
||||
if (cached_timestamp_type == TIMESTAMP_TIME && ltime->day)
|
||||
{
|
||||
/*
|
||||
Day part for time type can be nonzero value and so
|
||||
we should add hours from day part to hour part to
|
||||
keep valid time value.
|
||||
*/
|
||||
ltime->hour+= ltime->day*24;
|
||||
ltime->day= 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
null_date:
|
||||
@ -2344,29 +2504,22 @@ String *Item_func_str_to_date::val_str(String *str)
|
||||
if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
The following DATE_TIME should be done dynamicly based on the
|
||||
format string (wen it's a constant). For example, we should only return
|
||||
microseconds if there was an %f in the format
|
||||
*/
|
||||
if (!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
|
||||
if (!make_datetime((const_item ? cached_format_type :
|
||||
(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME)),
|
||||
<ime, str))
|
||||
return str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_last_day::val_str(String *str)
|
||||
bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date)
|
||||
{
|
||||
TIME ltime;
|
||||
if (!get_arg0_date(<ime,0))
|
||||
{
|
||||
uint month_idx= ltime.month-1;
|
||||
ltime.day= days_in_month[month_idx];
|
||||
if ( month_idx == 1 && calc_days_in_year(ltime.year) == 366)
|
||||
ltime.day+= 1;
|
||||
if (!make_datetime(DATE_ONLY, <ime, str))
|
||||
return str;
|
||||
}
|
||||
if (get_arg0_date(ltime,fuzzy_date))
|
||||
return 1;
|
||||
uint month_idx= ltime->month-1;
|
||||
ltime->day= days_in_month[month_idx];
|
||||
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
|
||||
ltime->day= 29;
|
||||
ltime->time_type= TIMESTAMP_DATE;
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,6 +21,11 @@
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
enum date_time_format_types
|
||||
{
|
||||
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
|
||||
};
|
||||
|
||||
class Item_func_period_add :public Item_int_func
|
||||
{
|
||||
public:
|
||||
@ -318,6 +323,7 @@ public:
|
||||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
String *val_str(String *str);
|
||||
longlong val_int();
|
||||
double val() { return (double) val_int(); }
|
||||
const char *func_name() const { return "date"; }
|
||||
void fix_length_and_dec()
|
||||
@ -407,6 +413,7 @@ public:
|
||||
Item_func_curdate() :Item_date() {}
|
||||
void set_result_from_tm(struct tm *now);
|
||||
longlong val_int() { return (value) ; }
|
||||
String *val_str(String *str);
|
||||
void fix_length_and_dec();
|
||||
bool get_date(TIME *res, uint fuzzy_date);
|
||||
virtual void store_now_in_tm(time_t now, struct tm *now_tm)=0;
|
||||
@ -477,8 +484,8 @@ class Item_func_from_days :public Item_date
|
||||
{
|
||||
public:
|
||||
Item_func_from_days(Item *a) :Item_date(a) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "from_days"; }
|
||||
bool get_date(TIME *res, uint fuzzy_date);
|
||||
};
|
||||
|
||||
|
||||
@ -806,37 +813,29 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class Item_func_str_to_date :public Item_date_func
|
||||
class Item_func_str_to_date :public Item_str_func
|
||||
{
|
||||
enum_field_types cached_field_type;
|
||||
date_time_format_types cached_format_type;
|
||||
timestamp_type cached_timestamp_type;
|
||||
bool const_item;
|
||||
public:
|
||||
Item_func_str_to_date(Item *a, Item *b)
|
||||
:Item_date_func(a, b)
|
||||
:Item_str_func(a, b)
|
||||
{}
|
||||
String *val_str(String *str);
|
||||
bool get_date(TIME *ltime, uint fuzzy_date);
|
||||
const char *func_name() const { return "str_to_date"; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
maybe_null= 1;
|
||||
decimals=0;
|
||||
max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
}
|
||||
enum_field_types field_type() const { return cached_field_type; }
|
||||
void fix_length_and_dec();
|
||||
Field *tmp_table_field(TABLE *t_arg);
|
||||
};
|
||||
|
||||
class Item_func_last_day :public Item_str_func
|
||||
|
||||
class Item_func_last_day :public Item_date
|
||||
{
|
||||
public:
|
||||
Item_func_last_day(Item *a) :Item_str_func(a) {}
|
||||
String *val_str(String *str);
|
||||
Item_func_last_day(Item *a) :Item_date(a) {}
|
||||
const char *func_name() const { return "last_day"; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
decimals=0;
|
||||
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||
}
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
|
||||
}
|
||||
bool get_date(TIME *res, uint fuzzy_date);
|
||||
};
|
||||
|
@ -799,6 +799,7 @@ extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
|
||||
extern char pidfile_name[FN_REFLEN], time_zone[30], *opt_init_file;
|
||||
extern char log_error_file[FN_REFLEN];
|
||||
extern double log_10[32];
|
||||
extern ulonglong log_10_int[20];
|
||||
extern ulonglong keybuff_size;
|
||||
extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
|
||||
extern ulong created_tmp_tables, created_tmp_disk_tables, bytes_sent;
|
||||
@ -958,6 +959,8 @@ timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time,
|
||||
void localtime_to_TIME(TIME *to, struct tm *from);
|
||||
void calc_time_from_sec(TIME *to, long seconds, long microseconds);
|
||||
|
||||
void make_truncated_value_warning(THD *thd, const char *str_val,
|
||||
uint str_length, timestamp_type time_type);
|
||||
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
|
||||
const char *format_str,
|
||||
uint format_length);
|
||||
|
@ -305,6 +305,14 @@ ulong my_bind_addr; /* the address we bind to */
|
||||
volatile ulong cached_thread_count= 0;
|
||||
|
||||
double log_10[32]; /* 10 potences */
|
||||
ulonglong log_10_int[20]=
|
||||
{
|
||||
1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL,
|
||||
100000000UL, 1000000000UL, 10000000000UL, 100000000000UL,
|
||||
1000000000000UL, 10000000000000UL, 100000000000000UL,
|
||||
1000000000000000UL, 10000000000000000UL, 100000000000000000UL,
|
||||
1000000000000000000UL, 10000000000000000000UL
|
||||
};
|
||||
|
||||
time_t start_time;
|
||||
|
||||
|
@ -304,3 +304,4 @@ character-set=latin2
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -298,3 +298,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -306,3 +306,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -300,3 +300,4 @@ character-set=latin7
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -307,3 +307,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -295,3 +295,4 @@ character-set=greek
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -297,3 +297,4 @@ character-set=latin2
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -297,3 +297,4 @@ character-set=ujis
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -295,3 +295,4 @@ character-set=euckr
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -297,3 +297,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -297,3 +297,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -299,3 +299,4 @@ character-set=latin2
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -296,3 +296,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -299,3 +299,4 @@ character-set=latin2
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -297,3 +297,4 @@ character-set=koi8r
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -289,3 +289,4 @@ character-set=cp1250
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working"
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement"
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -303,3 +303,4 @@ character-set=latin2
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -297,3 +297,4 @@ character-set=latin1
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -295,3 +295,4 @@ character-set=latin1
|
||||
"MySQL är started i --skip-grant-tables mod. Pga av detta kan du inte använda detta program",
|
||||
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
@ -300,3 +300,4 @@ character-set=koi8u
|
||||
"The '%s' feature was disabled; you need MySQL built with '%s' to have it working",
|
||||
"The MySQL server is running with the %s option so it cannot execute this statement",
|
||||
"Column '%-.100s' has duplicated value '%-.64s' in %s"
|
||||
"Truncated wrong %-.32s value: '%-.128s'"
|
||||
|
80
sql/time.cc
80
sql/time.cc
@ -391,9 +391,11 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
||||
ulong not_zero_date, allow_space;
|
||||
bool is_internal_format;
|
||||
const char *pos, *last_field_pos;
|
||||
const char *str_begin= str;
|
||||
const char *end=str+length;
|
||||
const uchar *format_position;
|
||||
bool found_delimitier= 0, found_space= 0;
|
||||
uint frac_pos, frac_len;
|
||||
DBUG_ENTER("str_to_TIME");
|
||||
DBUG_PRINT("ENTER",("str: %.*s",length,str));
|
||||
|
||||
@ -482,7 +484,7 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
||||
tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0');
|
||||
str++;
|
||||
}
|
||||
date_len[i]+= (uint) (str - start);
|
||||
date_len[i]= (uint) (str - start);
|
||||
if (tmp_value > 999999) // Impossible date part
|
||||
DBUG_RETURN(TIMESTAMP_NONE);
|
||||
date[i]=tmp_value;
|
||||
@ -535,9 +537,9 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
||||
{
|
||||
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
|
||||
{
|
||||
if (str[1] == 'p' || str[1] == 'P')
|
||||
if (str[0] == 'p' || str[0] == 'P')
|
||||
add_hours= 12;
|
||||
else if (str[1] != 'a' || str[1] != 'A')
|
||||
else if (str[0] != 'a' || str[0] != 'A')
|
||||
continue; // Not AM/PM
|
||||
str+= 2; // Skip AM/PM
|
||||
/* Skip space after AM/PM */
|
||||
@ -569,7 +571,13 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
||||
l_time->hour= date[(uint) format_position[3]];
|
||||
l_time->minute= date[(uint) format_position[4]];
|
||||
l_time->second= date[(uint) format_position[5]];
|
||||
l_time->second_part= date[(uint) format_position[6]];
|
||||
|
||||
frac_pos= (uint) format_position[6];
|
||||
frac_len= date_len[frac_pos];
|
||||
if (frac_len < 6)
|
||||
date[frac_pos]*= (uint) log_10_int[6 - frac_len];
|
||||
l_time->second_part= date[frac_pos];
|
||||
|
||||
if (format_position[7] != (uchar) 255)
|
||||
{
|
||||
if (l_time->hour > 12)
|
||||
@ -585,6 +593,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
||||
l_time->hour= date[3];
|
||||
l_time->minute= date[4];
|
||||
l_time->second= date[5];
|
||||
if (date_len[6] < 6)
|
||||
date[6]*= (uint) log_10_int[6 - date_len[6]];
|
||||
l_time->second_part=date[6];
|
||||
}
|
||||
l_time->neg= 0;
|
||||
@ -614,15 +624,17 @@ str_to_TIME(const char *str, uint length, TIME *l_time, uint flags)
|
||||
current_thd->cuted_fields++;
|
||||
goto err;
|
||||
}
|
||||
if (str != end && current_thd->count_cuted_fields)
|
||||
|
||||
l_time->time_type= (number_of_fields <= 3 ?
|
||||
TIMESTAMP_DATE : TIMESTAMP_DATETIME);
|
||||
|
||||
for (; str != end ; str++)
|
||||
{
|
||||
for (; str != end ; str++)
|
||||
if (!my_isspace(&my_charset_latin1,*str))
|
||||
{
|
||||
if (!my_isspace(&my_charset_latin1,*str))
|
||||
{
|
||||
current_thd->cuted_fields++;
|
||||
break;
|
||||
}
|
||||
make_truncated_value_warning(current_thd, str_begin, length,
|
||||
l_time->time_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -686,6 +698,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
|
||||
{
|
||||
long date[5],value;
|
||||
const char *end=str+length, *end_of_days;
|
||||
const char *str_begin= str;
|
||||
bool found_days,found_hours;
|
||||
uint state;
|
||||
|
||||
@ -706,7 +719,7 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
|
||||
{ // Probably full timestamp
|
||||
enum timestamp_type res= str_to_TIME(str,length,l_time,
|
||||
(TIME_FUZZY_DATE |
|
||||
TIME_DATETIME_ONLY));
|
||||
TIME_DATETIME_ONLY));
|
||||
if ((int) res >= (int) TIMESTAMP_DATETIME_ERROR)
|
||||
return res == TIMESTAMP_DATETIME_ERROR;
|
||||
}
|
||||
@ -784,6 +797,8 @@ fractional:
|
||||
my_isdigit(&my_charset_latin1,str[0]) &&
|
||||
field_length--)
|
||||
value=value*10 + (uint) (uchar) (*str - '0');
|
||||
if (field_length)
|
||||
value*= (long) log_10_int[field_length];
|
||||
date[4]=value;
|
||||
}
|
||||
else
|
||||
@ -796,12 +811,12 @@ fractional:
|
||||
str++;
|
||||
if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
|
||||
{
|
||||
if (str[1] == 'p' || str[1] == 'P')
|
||||
if (str[0] == 'p' || str[0] == 'P')
|
||||
{
|
||||
str+= 2;
|
||||
date[1]= date[1]%12 + 12;
|
||||
}
|
||||
else if (str[1] == 'a' || str[1] == 'A')
|
||||
else if (str[0] == 'a' || str[0] == 'A')
|
||||
str+=2;
|
||||
}
|
||||
}
|
||||
@ -822,13 +837,14 @@ fractional:
|
||||
l_time->time_type= TIMESTAMP_TIME;
|
||||
|
||||
/* Check if there is garbage at end of the TIME specification */
|
||||
if (str != end && current_thd->count_cuted_fields)
|
||||
if (str != end)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!my_isspace(&my_charset_latin1,*str))
|
||||
{
|
||||
current_thd->cuted_fields++;
|
||||
make_truncated_value_warning(current_thd, str_begin, length,
|
||||
TIMESTAMP_TIME);
|
||||
break;
|
||||
}
|
||||
} while (++str != end);
|
||||
@ -1265,3 +1281,35 @@ void make_datetime(DATE_TIME_FORMAT *format, TIME *l_time, String *str)
|
||||
str->length(length);
|
||||
str->set_charset(&my_charset_bin);
|
||||
}
|
||||
|
||||
void make_truncated_value_warning(THD *thd, const char *str_val,
|
||||
uint str_length, timestamp_type time_type)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
const char *type_str;
|
||||
|
||||
char buff[128];
|
||||
String str(buff,(uint32) sizeof(buff), system_charset_info);
|
||||
str.length(0);
|
||||
str.append(str_val, str_length);
|
||||
str.append('\0');
|
||||
|
||||
switch (time_type) {
|
||||
case TIMESTAMP_DATE:
|
||||
type_str= "date";
|
||||
break;
|
||||
case TIMESTAMP_DATETIME:
|
||||
type_str= "datetime";
|
||||
break;
|
||||
case TIMESTAMP_TIME:
|
||||
type_str= "time";
|
||||
break;
|
||||
default:
|
||||
type_str= "string";
|
||||
break;
|
||||
}
|
||||
sprintf(warn_buff, ER(ER_TRUNCATED_WRONG_VALUE),
|
||||
type_str, str.ptr());
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_TRUNCATED_WRONG_VALUE, warn_buff);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user