Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
a82e5d4a
Commit
a82e5d4a
authored
Oct 12, 2006
by
kaa@polly.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge polly.local:/tmp/maint/bug11655/my51-bug11655
into polly.local:/home/kaa/src/maint/m51-new-maint--07OGx
parents
a9c3db68
105434f8
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
427 additions
and
93 deletions
+427
-93
include/my_time.h
include/my_time.h
+13
-1
mysql-test/r/func_sapdb.result
mysql-test/r/func_sapdb.result
+11
-4
mysql-test/r/func_time.result
mysql-test/r/func_time.result
+90
-1
mysql-test/t/func_time.test
mysql-test/t/func_time.test
+41
-0
sql-common/my_time.c
sql-common/my_time.c
+69
-21
sql/field.cc
sql/field.cc
+17
-18
sql/item_timefunc.cc
sql/item_timefunc.cc
+183
-45
sql/time.cc
sql/time.cc
+3
-3
No files found.
include/my_time.h
View file @
a82e5d4a
...
@@ -57,6 +57,16 @@ typedef long my_time_t;
...
@@ -57,6 +57,16 @@ typedef long my_time_t;
#define TIME_NO_ZERO_DATE (TIME_NO_ZERO_IN_DATE*2)
#define TIME_NO_ZERO_DATE (TIME_NO_ZERO_IN_DATE*2)
#define TIME_INVALID_DATES (TIME_NO_ZERO_DATE*2)
#define TIME_INVALID_DATES (TIME_NO_ZERO_DATE*2)
#define MYSQL_TIME_WARN_TRUNCATED 1
#define MYSQL_TIME_WARN_OUT_OF_RANGE 2
/* Limits for the TIME data type */
#define TIME_MAX_HOUR 838
#define TIME_MAX_MINUTE 59
#define TIME_MAX_SECOND 59
#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \
TIME_MAX_SECOND)
enum
enum_mysql_timestamp_type
enum
enum_mysql_timestamp_type
str_to_datetime
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
str_to_datetime
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
uint
flags
,
int
*
was_cut
);
uint
flags
,
int
*
was_cut
);
...
@@ -69,7 +79,9 @@ ulonglong TIME_to_ulonglong(const MYSQL_TIME *time);
...
@@ -69,7 +79,9 @@ ulonglong TIME_to_ulonglong(const MYSQL_TIME *time);
my_bool
str_to_time
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
my_bool
str_to_time
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
int
*
was_cut
);
int
*
warning
);
int
check_time_range
(
struct
st_mysql_time
*
time
,
int
*
warning
);
long
calc_daynr
(
uint
year
,
uint
month
,
uint
day
);
long
calc_daynr
(
uint
year
,
uint
month
,
uint
day
);
uint
calc_days_in_year
(
uint
year
);
uint
calc_days_in_year
(
uint
year
);
...
...
mysql-test/r/func_sapdb.result
View file @
a82e5d4a
...
@@ -107,7 +107,9 @@ subtime("02:01:01.999999", "01:01:01.999999")
...
@@ -107,7 +107,9 @@ subtime("02:01:01.999999", "01:01:01.999999")
01:00:00.000000
01:00:00.000000
select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002");
timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002")
timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002")
8807:59:59.999999
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '8807:59:59.999999'
select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002");
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002")
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002")
46:58:57.999999
46:58:57.999999
...
@@ -219,13 +221,16 @@ SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq,
...
@@ -219,13 +221,16 @@ SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq,
TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test;
TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test;
ttt qqq eee rrr
ttt qqq eee rrr
-744:00:00 NULL NULL NULL
-744:00:00 NULL NULL NULL
26305:01:02
22:58:58 -22:58:58 NULL
838:59:59
22:58:58 -22:58:58 NULL
-
26305:01:02
-22:58:58 22:58:58 NULL
-
838:59:59
-22:58:58 22:58:58 NULL
NULL 26:02:02 -26:02:02 NULL
NULL 26:02:02 -26:02:02 NULL
00:00:00 -26:02:02 26:02:02 NULL
00:00:00 -26:02:02 26:02:02 NULL
NULL NULL NULL NULL
NULL NULL NULL NULL
NULL NULL NULL NULL
NULL NULL NULL NULL
00:00:00 -24:00:00 24:00:00 NULL
00:00:00 -24:00:00 24:00:00 NULL
Warnings:
Warning 1292 Truncated incorrect time value: '26305:01:02'
Warning 1292 Truncated incorrect time value: '-26305:01:02'
drop table t1, test;
drop table t1, test;
select addtime("-01:01:01.01", "-23:59:59.1") as a;
select addtime("-01:01:01.01", "-23:59:59.1") as a;
a
a
...
@@ -235,7 +240,9 @@ a
...
@@ -235,7 +240,9 @@ a
10000
10000
select microsecond(19971231235959.01) as a;
select microsecond(19971231235959.01) as a;
a
a
10000
0
Warnings:
Warning 1292 Truncated incorrect time value: '19971231235959.01'
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a;
a
a
1997-12-31 00:00:10.090000
1997-12-31 00:00:10.090000
...
...
mysql-test/r/func_time.result
View file @
a82e5d4a
...
@@ -339,7 +339,9 @@ extract(DAY_MINUTE FROM "02 10:11:12")
...
@@ -339,7 +339,9 @@ extract(DAY_MINUTE FROM "02 10:11:12")
21011
21011
select extract(DAY_SECOND FROM "225 10:11:12");
select extract(DAY_SECOND FROM "225 10:11:12");
extract(DAY_SECOND FROM "225 10:11:12")
extract(DAY_SECOND FROM "225 10:11:12")
225101112
8385959
Warnings:
Warning 1292 Truncated incorrect time value: '225 10:11:12'
select extract(HOUR FROM "1999-01-02 10:11:12");
select extract(HOUR FROM "1999-01-02 10:11:12");
extract(HOUR FROM "1999-01-02 10:11:12")
extract(HOUR FROM "1999-01-02 10:11:12")
10
10
...
@@ -902,6 +904,93 @@ fmtddate field2
...
@@ -902,6 +904,93 @@ fmtddate field2
Sep-4 12:00AM abcd
Sep-4 12:00AM abcd
DROP TABLE testBug8868;
DROP TABLE testBug8868;
SET NAMES DEFAULT;
SET NAMES DEFAULT;
SELECT SEC_TO_TIME(3300000);
SEC_TO_TIME(3300000)
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '3300000'
SELECT SEC_TO_TIME(3300000)+0;
SEC_TO_TIME(3300000)+0
8385959.000000
Warnings:
Warning 1292 Truncated incorrect time value: '3300000'
SELECT SEC_TO_TIME(3600 * 4294967296);
SEC_TO_TIME(3600 * 4294967296)
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '15461882265600'
SELECT TIME_TO_SEC('916:40:00');
TIME_TO_SEC('916:40:00')
3020399
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
SELECT ADDTIME('500:00:00', '416:40:00');
ADDTIME('500:00:00', '416:40:00')
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
SELECT ADDTIME('916:40:00', '416:40:00');
ADDTIME('916:40:00', '416:40:00')
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
Warning 1292 Truncated incorrect time value: '1255:39:59'
SELECT SUBTIME('916:40:00', '416:40:00');
SUBTIME('916:40:00', '416:40:00')
422:19:59
Warnings:
Warning 1292 Truncated incorrect time value: '916:40:00'
SELECT SUBTIME('-916:40:00', '416:40:00');
SUBTIME('-916:40:00', '416:40:00')
-838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '-916:40:00'
Warning 1292 Truncated incorrect time value: '-1255:39:59'
SELECT MAKETIME(916,0,0);
MAKETIME(916,0,0)
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '916:00:00'
SELECT MAKETIME(4294967296, 0, 0);
MAKETIME(4294967296, 0, 0)
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '4294967296:00:00'
SELECT MAKETIME(-4294967296, 0, 0);
MAKETIME(-4294967296, 0, 0)
-838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '-4294967296:00:00'
SELECT MAKETIME(0, 4294967296, 0);
MAKETIME(0, 4294967296, 0)
NULL
SELECT MAKETIME(0, 0, 4294967296);
MAKETIME(0, 0, 4294967296)
NULL
SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0);
MAKETIME(CAST(-1 AS UNSIGNED), 0, 0)
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00'
SELECT EXTRACT(HOUR FROM '100000:02:03');
EXTRACT(HOUR FROM '100000:02:03')
838
Warnings:
Warning 1292 Truncated incorrect time value: '100000:02:03'
CREATE TABLE t1(f1 TIME);
INSERT INTO t1 VALUES('916:00:00 a');
Warnings:
Warning 1265 Data truncated for column 'f1' at row 1
Warning 1264 Out of range value adjusted for column 'f1' at row 1
SELECT * FROM t1;
f1
838:59:59
DROP TABLE t1;
SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED));
SEC_TO_TIME(CAST(-1 AS UNSIGNED))
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '18446744073709551615'
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H)
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H)
union
union
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H);
(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H);
...
...
mysql-test/t/func_time.test
View file @
a82e5d4a
...
@@ -466,6 +466,47 @@ SET NAMES DEFAULT;
...
@@ -466,6 +466,47 @@ SET NAMES DEFAULT;
#
#
# Bug #11655: Wrong time is returning from nested selects - maximum time exists
#
# check if SEC_TO_TIME() handles out-of-range values correctly
SELECT
SEC_TO_TIME
(
3300000
);
SELECT
SEC_TO_TIME
(
3300000
)
+
0
;
SELECT
SEC_TO_TIME
(
3600
*
4294967296
);
# check if TIME_TO_SEC() handles out-of-range values correctly
SELECT
TIME_TO_SEC
(
'916:40:00'
);
# check if ADDTIME() handles out-of-range values correctly
SELECT
ADDTIME
(
'500:00:00'
,
'416:40:00'
);
SELECT
ADDTIME
(
'916:40:00'
,
'416:40:00'
);
# check if SUBTIME() handles out-of-range values correctly
SELECT
SUBTIME
(
'916:40:00'
,
'416:40:00'
);
SELECT
SUBTIME
(
'-916:40:00'
,
'416:40:00'
);
# check if MAKETIME() handles out-of-range values correctly
SELECT
MAKETIME
(
916
,
0
,
0
);
SELECT
MAKETIME
(
4294967296
,
0
,
0
);
SELECT
MAKETIME
(
-
4294967296
,
0
,
0
);
SELECT
MAKETIME
(
0
,
4294967296
,
0
);
SELECT
MAKETIME
(
0
,
0
,
4294967296
);
SELECT
MAKETIME
(
CAST
(
-
1
AS
UNSIGNED
),
0
,
0
);
# check if EXTRACT() handles out-of-range values correctly
SELECT
EXTRACT
(
HOUR
FROM
'100000:02:03'
);
# check if we get proper warnings if both input string truncation
# and out-of-range value occur
CREATE
TABLE
t1
(
f1
TIME
);
INSERT
INTO
t1
VALUES
(
'916:00:00 a'
);
SELECT
*
FROM
t1
;
DROP
TABLE
t1
;
#
# Bug #20927: sec_to_time treats big unsigned as signed
#
# check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly
SELECT
SEC_TO_TIME
(
CAST
(
-
1
AS
UNSIGNED
));
# Bug #19844 time_format in Union truncates values
# Bug #19844 time_format in Union truncates values
#
#
...
...
sql-common/my_time.c
View file @
a82e5d4a
...
@@ -465,8 +465,10 @@ err:
...
@@ -465,8 +465,10 @@ err:
There may be an optional [.second_part] after seconds
There may be an optional [.second_part] after seconds
length Length of str
length Length of str
l_time Store result here
l_time Store result here
was_cut Set to 1 if value was cut during conversion or to 0
warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string
otherwise.
was cut during conversion, and/or
MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is
out of range.
NOTES
NOTES
Because of the extra days argument, this function can only
Because of the extra days argument, this function can only
...
@@ -478,15 +480,16 @@ err:
...
@@ -478,15 +480,16 @@ err:
*/
*/
my_bool
str_to_time
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
my_bool
str_to_time
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
int
*
wa
s_cut
)
int
*
wa
rning
)
{
{
long
date
[
5
],
value
;
ulong
date
[
5
];
ulonglong
value
;
const
char
*
end
=
str
+
length
,
*
end_of_days
;
const
char
*
end
=
str
+
length
,
*
end_of_days
;
my_bool
found_days
,
found_hours
;
my_bool
found_days
,
found_hours
;
uint
state
;
uint
state
;
l_time
->
neg
=
0
;
l_time
->
neg
=
0
;
*
wa
s_cut
=
0
;
*
wa
rning
=
0
;
for
(;
str
!=
end
&&
my_isspace
(
&
my_charset_latin1
,
*
str
)
;
str
++
)
for
(;
str
!=
end
&&
my_isspace
(
&
my_charset_latin1
,
*
str
)
;
str
++
)
length
--
;
length
--
;
if
(
str
!=
end
&&
*
str
==
'-'
)
if
(
str
!=
end
&&
*
str
==
'-'
)
...
@@ -501,13 +504,16 @@ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
...
@@ -501,13 +504,16 @@ my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
/* Check first if this is a full TIMESTAMP */
/* Check first if this is a full TIMESTAMP */
if
(
length
>=
12
)
if
(
length
>=
12
)
{
/* Probably full timestamp */
{
/* Probably full timestamp */
int
was_cut
;
enum
enum_mysql_timestamp_type
enum
enum_mysql_timestamp_type
res
=
str_to_datetime
(
str
,
length
,
l_time
,
res
=
str_to_datetime
(
str
,
length
,
l_time
,
(
TIME_FUZZY_DATE
|
TIME_DATETIME_ONLY
),
was_cut
);
(
TIME_FUZZY_DATE
|
TIME_DATETIME_ONLY
),
&
was_cut
);
if
((
int
)
res
>=
(
int
)
MYSQL_TIMESTAMP_ERROR
)
if
((
int
)
res
>=
(
int
)
MYSQL_TIMESTAMP_ERROR
)
{
if
(
was_cut
)
*
warning
|=
MYSQL_TIME_WARN_TRUNCATED
;
return
res
==
MYSQL_TIMESTAMP_ERROR
;
return
res
==
MYSQL_TIMESTAMP_ERROR
;
/* We need to restore was_cut flag since str_to_datetime can modify it */
}
*
was_cut
=
0
;
}
}
/* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
/* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
...
@@ -587,7 +593,7 @@ fractional:
...
@@ -587,7 +593,7 @@ fractional:
if
(
field_length
>
0
)
if
(
field_length
>
0
)
value
*=
(
long
)
log_10_int
[
field_length
];
value
*=
(
long
)
log_10_int
[
field_length
];
else
if
(
field_length
<
0
)
else
if
(
field_length
<
0
)
*
wa
s_cut
=
1
;
*
wa
rning
|=
MYSQL_TIME_WARN_TRUNCATED
;
date
[
4
]
=
value
;
date
[
4
]
=
value
;
}
}
else
else
...
@@ -601,10 +607,7 @@ fractional:
...
@@ -601,10 +607,7 @@ fractional:
((
str
[
1
]
==
'-'
||
str
[
1
]
==
'+'
)
&&
((
str
[
1
]
==
'-'
||
str
[
1
]
==
'+'
)
&&
(
end
-
str
)
>
2
&&
(
end
-
str
)
>
2
&&
my_isdigit
(
&
my_charset_latin1
,
str
[
2
]))))
my_isdigit
(
&
my_charset_latin1
,
str
[
2
]))))
{
*
was_cut
=
1
;
return
1
;
return
1
;
}
if
(
internal_format_positions
[
7
]
!=
255
)
if
(
internal_format_positions
[
7
]
!=
255
)
{
{
...
@@ -623,12 +626,12 @@ fractional:
...
@@ -623,12 +626,12 @@ fractional:
}
}
}
}
/*
Some simple
checks */
/*
Integer overflow
checks */
if
(
date
[
2
]
>=
60
||
date
[
3
]
>=
60
)
if
(
date
[
0
]
>
UINT_MAX
||
date
[
1
]
>
UINT_MAX
||
{
date
[
2
]
>
UINT_MAX
||
date
[
3
]
>
UINT_MAX
||
*
was_cut
=
1
;
date
[
4
]
>
UINT_MAX
)
return
1
;
return
1
;
}
l_time
->
year
=
0
;
/* For protocol::store_time */
l_time
->
year
=
0
;
/* For protocol::store_time */
l_time
->
month
=
0
;
l_time
->
month
=
0
;
l_time
->
day
=
date
[
0
];
l_time
->
day
=
date
[
0
];
...
@@ -638,6 +641,10 @@ fractional:
...
@@ -638,6 +641,10 @@ fractional:
l_time
->
second_part
=
date
[
4
];
l_time
->
second_part
=
date
[
4
];
l_time
->
time_type
=
MYSQL_TIMESTAMP_TIME
;
l_time
->
time_type
=
MYSQL_TIMESTAMP_TIME
;
/* Check if the value is valid and fits into TIME range */
if
(
check_time_range
(
l_time
,
warning
))
return
1
;
/* Check if there is garbage at end of the TIME specification */
/* Check if there is garbage at end of the TIME specification */
if
(
str
!=
end
)
if
(
str
!=
end
)
{
{
...
@@ -645,7 +652,7 @@ fractional:
...
@@ -645,7 +652,7 @@ fractional:
{
{
if
(
!
my_isspace
(
&
my_charset_latin1
,
*
str
))
if
(
!
my_isspace
(
&
my_charset_latin1
,
*
str
))
{
{
*
wa
s_cut
=
1
;
*
wa
rning
|=
MYSQL_TIME_WARN_TRUNCATED
;
break
;
break
;
}
}
}
while
(
++
str
!=
end
);
}
while
(
++
str
!=
end
);
...
@@ -654,6 +661,47 @@ fractional:
...
@@ -654,6 +661,47 @@ fractional:
}
}
/*
Check 'time' value to lie in the TIME range
SYNOPSIS:
check_time_range()
time pointer to TIME value
warning set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range
DESCRIPTION
If the time value lies outside of the range [-838:59:59, 838:59:59],
set it to the closest endpoint of the range and set
MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable.
RETURN
0 time value is valid, but was possibly truncated
1 time value is invalid
*/
int
check_time_range
(
struct
st_mysql_time
*
time
,
int
*
warning
)
{
longlong
hour
;
if
(
time
->
minute
>=
60
||
time
->
second
>=
60
)
return
1
;
hour
=
time
->
hour
+
(
24
*
time
->
day
);
if
(
hour
<=
TIME_MAX_HOUR
&&
(
hour
!=
TIME_MAX_HOUR
||
time
->
minute
!=
TIME_MAX_MINUTE
||
time
->
second
!=
TIME_MAX_SECOND
||
!
time
->
second_part
))
return
0
;
time
->
day
=
0
;
time
->
hour
=
TIME_MAX_HOUR
;
time
->
minute
=
TIME_MAX_MINUTE
;
time
->
second
=
TIME_MAX_SECOND
;
time
->
second_part
=
0
;
*
warning
|=
MYSQL_TIME_WARN_OUT_OF_RANGE
;
return
0
;
}
/*
/*
Prepare offset of system time zone from UTC for my_system_gmt_sec() func.
Prepare offset of system time zone from UTC for my_system_gmt_sec() func.
...
@@ -840,7 +888,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
...
@@ -840,7 +888,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type)
int
my_time_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
)
int
my_time_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
)
{
{
uint
extra_hours
=
0
;
uint
extra_hours
=
0
;
return
my_sprintf
(
to
,
(
to
,
"%s%02
d:%02d:%02d
"
,
return
my_sprintf
(
to
,
(
to
,
"%s%02
u:%02u:%02u
"
,
(
l_time
->
neg
?
"-"
:
""
),
(
l_time
->
neg
?
"-"
:
""
),
extra_hours
+
l_time
->
hour
,
extra_hours
+
l_time
->
hour
,
l_time
->
minute
,
l_time
->
minute
,
...
@@ -849,7 +897,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to)
...
@@ -849,7 +897,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to)
int
my_date_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
)
int
my_date_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
)
{
{
return
my_sprintf
(
to
,
(
to
,
"%04
d-%02d-%02d
"
,
return
my_sprintf
(
to
,
(
to
,
"%04
u-%02u-%02u
"
,
l_time
->
year
,
l_time
->
year
,
l_time
->
month
,
l_time
->
month
,
l_time
->
day
));
l_time
->
day
));
...
@@ -857,7 +905,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to)
...
@@ -857,7 +905,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to)
int
my_datetime_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
)
int
my_datetime_to_str
(
const
MYSQL_TIME
*
l_time
,
char
*
to
)
{
{
return
my_sprintf
(
to
,
(
to
,
"%04
d-%02d-%02d %02d:%02d:%02d
"
,
return
my_sprintf
(
to
,
(
to
,
"%04
u-%02u-%02u %02u:%02u:%02u
"
,
l_time
->
year
,
l_time
->
year
,
l_time
->
month
,
l_time
->
month
,
l_time
->
day
,
l_time
->
day
,
...
...
sql/field.cc
View file @
a82e5d4a
...
@@ -4875,9 +4875,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
...
@@ -4875,9 +4875,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
{
{
TIME
ltime
;
TIME
ltime
;
long
tmp
;
long
tmp
;
int
error
;
int
error
=
0
;
int
warning
;
if
(
str_to_time
(
from
,
len
,
&
ltime
,
&
error
))
if
(
str_to_time
(
from
,
len
,
&
ltime
,
&
warning
))
{
{
tmp
=
0L
;
tmp
=
0L
;
error
=
2
;
error
=
2
;
...
@@ -4886,29 +4887,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
...
@@ -4886,29 +4887,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
}
}
else
else
{
{
if
(
error
)
if
(
warning
&
MYSQL_TIME_WARN_TRUNCATED
)
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_DATA_TRUNCATED
,
WARN_DATA_TRUNCATED
,
from
,
len
,
MYSQL_TIMESTAMP_TIME
,
1
);
from
,
len
,
MYSQL_TIMESTAMP_TIME
,
1
);
if
(
warning
&
MYSQL_TIME_WARN_OUT_OF_RANGE
)
if
(
ltime
.
month
)
ltime
.
day
=
0
;
tmp
=
(
ltime
.
day
*
24L
+
ltime
.
hour
)
*
10000L
+
(
ltime
.
minute
*
100
+
ltime
.
second
);
if
(
tmp
>
8385959
)
{
{
tmp
=
8385959
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
ER_WARN_DATA_OUT_OF_RANGE
,
from
,
len
,
MYSQL_TIMESTAMP_TIME
,
!
error
);
from
,
len
,
MYSQL_TIMESTAMP_TIME
,
!
error
);
error
=
1
;
error
=
1
;
}
}
if
(
ltime
.
month
)
ltime
.
day
=
0
;
tmp
=
(
ltime
.
day
*
24L
+
ltime
.
hour
)
*
10000L
+
(
ltime
.
minute
*
100
+
ltime
.
second
);
if
(
error
>
1
)
if
(
error
>
1
)
error
=
2
;
error
=
2
;
}
}
if
(
ltime
.
neg
)
if
(
ltime
.
neg
)
tmp
=
-
tmp
;
tmp
=
-
tmp
;
error
|=
Field_time
::
store
((
longlong
)
tmp
,
FALSE
);
int3store
(
ptr
,
tmp
);
return
error
;
return
error
;
}
}
...
@@ -4928,16 +4927,16 @@ int Field_time::store(double nr)
...
@@ -4928,16 +4927,16 @@ int Field_time::store(double nr)
ASSERT_COLUMN_MARKED_FOR_WRITE
;
ASSERT_COLUMN_MARKED_FOR_WRITE
;
long
tmp
;
long
tmp
;
int
error
=
0
;
int
error
=
0
;
if
(
nr
>
8385959.0
)
if
(
nr
>
(
double
)
TIME_MAX_VALUE
)
{
{
tmp
=
8385959L
;
tmp
=
TIME_MAX_VALUE
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
);
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
);
error
=
1
;
error
=
1
;
}
}
else
if
(
nr
<
-
8385959.0
)
else
if
(
nr
<
(
double
)
-
TIME_MAX_VALUE
)
{
{
tmp
=
-
8385959L
;
tmp
=
-
TIME_MAX_VALUE
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
);
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
);
error
=
1
;
error
=
1
;
...
@@ -4966,17 +4965,17 @@ int Field_time::store(longlong nr, bool unsigned_val)
...
@@ -4966,17 +4965,17 @@ int Field_time::store(longlong nr, bool unsigned_val)
ASSERT_COLUMN_MARKED_FOR_WRITE
;
ASSERT_COLUMN_MARKED_FOR_WRITE
;
long
tmp
;
long
tmp
;
int
error
=
0
;
int
error
=
0
;
if
(
nr
<
(
longlong
)
-
8385959L
&&
!
unsigned_val
)
if
(
nr
<
(
longlong
)
-
TIME_MAX_VALUE
&&
!
unsigned_val
)
{
{
tmp
=
-
8385959L
;
tmp
=
-
TIME_MAX_VALUE
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
,
1
);
MYSQL_TIMESTAMP_TIME
,
1
);
error
=
1
;
error
=
1
;
}
}
else
if
(
nr
>
(
longlong
)
8385959
||
nr
<
0
&&
unsigned_val
)
else
if
(
nr
>
(
longlong
)
TIME_MAX_VALUE
||
nr
<
0
&&
unsigned_val
)
{
{
tmp
=
8385959L
;
tmp
=
TIME_MAX_VALUE
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
,
1
);
MYSQL_TIMESTAMP_TIME
,
1
);
...
...
sql/item_timefunc.cc
View file @
a82e5d4a
...
@@ -95,6 +95,125 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
...
@@ -95,6 +95,125 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
}
}
/*
Wrapper over make_datetime() with validation of the input TIME value
NOTE
see make_datetime() for more information
RETURN
1 if there was an error during converion
0 otherwise
*/
static
bool
make_datetime_with_warn
(
date_time_format_types
format
,
TIME
*
ltime
,
String
*
str
)
{
int
warning
=
0
;
bool
rc
;
if
(
make_datetime
(
format
,
ltime
,
str
))
return
1
;
if
(
check_time_range
(
ltime
,
&
warning
))
return
1
;
if
(
!
warning
)
return
0
;
make_truncated_value_warning
(
current_thd
,
str
->
ptr
(),
str
->
length
(),
MYSQL_TIMESTAMP_TIME
,
NullS
);
return
make_datetime
(
format
,
ltime
,
str
);
}
/*
Wrapper over make_time() with validation of the input TIME value
NOTE
see make_time() for more info
RETURN
1 if there was an error during conversion
0 otherwise
*/
static
bool
make_time_with_warn
(
const
DATE_TIME_FORMAT
*
format
,
TIME
*
l_time
,
String
*
str
)
{
int
warning
=
0
;
make_time
(
format
,
l_time
,
str
);
if
(
check_time_range
(
l_time
,
&
warning
))
return
1
;
if
(
warning
)
{
make_truncated_value_warning
(
current_thd
,
str
->
ptr
(),
str
->
length
(),
MYSQL_TIMESTAMP_TIME
,
NullS
);
make_time
(
format
,
l_time
,
str
);
}
return
0
;
}
/*
Convert seconds to TIME value with overflow checking
SYNOPSIS:
sec_to_time()
seconds number of seconds
unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise
ltime output TIME value
DESCRIPTION
If the 'seconds' argument is inside TIME data range, convert it to a
corresponding value.
Otherwise, truncate the resulting value to the nearest endpoint, and
produce a warning message.
RETURN
1 if the value was truncated during conversion
0 otherwise
*/
static
bool
sec_to_time
(
longlong
seconds
,
bool
unsigned_flag
,
TIME
*
ltime
)
{
uint
sec
;
bzero
((
char
*
)
ltime
,
sizeof
(
*
ltime
));
if
(
seconds
<
0
)
{
if
(
unsigned_flag
)
goto
overflow
;
ltime
->
neg
=
1
;
if
(
seconds
<
-
3020399
)
goto
overflow
;
seconds
=
-
seconds
;
}
else
if
(
seconds
>
3020399
)
goto
overflow
;
sec
=
(
uint
)
((
ulonglong
)
seconds
%
3600
);
ltime
->
hour
=
(
uint
)
(
seconds
/
3600
);
ltime
->
minute
=
sec
/
60
;
ltime
->
second
=
sec
%
60
;
return
0
;
overflow:
ltime
->
hour
=
TIME_MAX_HOUR
;
ltime
->
minute
=
TIME_MAX_MINUTE
;
ltime
->
second
=
TIME_MAX_SECOND
;
char
buf
[
22
];
int
len
=
(
int
)(
longlong10_to_str
(
seconds
,
buf
,
unsigned_flag
?
10
:
-
10
)
-
buf
);
make_truncated_value_warning
(
current_thd
,
buf
,
len
,
MYSQL_TIMESTAMP_TIME
,
NullS
);
return
1
;
}
/*
/*
Date formats corresponding to compound %r and %T conversion specifiers
Date formats corresponding to compound %r and %T conversion specifiers
...
@@ -1546,8 +1665,6 @@ int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions)
...
@@ -1546,8 +1665,6 @@ int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions)
String
*
Item_func_sec_to_time
::
val_str
(
String
*
str
)
String
*
Item_func_sec_to_time
::
val_str
(
String
*
str
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
longlong
seconds
=
(
longlong
)
args
[
0
]
->
val_int
();
uint
sec
;
TIME
ltime
;
TIME
ltime
;
if
((
null_value
=
args
[
0
]
->
null_value
)
||
str
->
alloc
(
19
))
if
((
null_value
=
args
[
0
]
->
null_value
)
||
str
->
alloc
(
19
))
...
@@ -1556,19 +1673,8 @@ String *Item_func_sec_to_time::val_str(String *str)
...
@@ -1556,19 +1673,8 @@ String *Item_func_sec_to_time::val_str(String *str)
return
(
String
*
)
0
;
return
(
String
*
)
0
;
}
}
ltime
.
neg
=
0
;
sec_to_time
(
args
[
0
]
->
val_int
(),
args
[
0
]
->
unsigned_flag
,
&
ltime
);
if
(
seconds
<
0
)
{
seconds
=
-
seconds
;
ltime
.
neg
=
1
;
}
sec
=
(
uint
)
((
ulonglong
)
seconds
%
3600
);
ltime
.
day
=
0
;
ltime
.
hour
=
(
uint
)
(
seconds
/
3600
);
ltime
.
minute
=
sec
/
60
;
ltime
.
second
=
sec
%
60
;
make_time
((
DATE_TIME_FORMAT
*
)
0
,
&
ltime
,
str
);
make_time
((
DATE_TIME_FORMAT
*
)
0
,
&
ltime
,
str
);
return
str
;
return
str
;
}
}
...
@@ -1577,16 +1683,15 @@ String *Item_func_sec_to_time::val_str(String *str)
...
@@ -1577,16 +1683,15 @@ String *Item_func_sec_to_time::val_str(String *str)
longlong
Item_func_sec_to_time
::
val_int
()
longlong
Item_func_sec_to_time
::
val_int
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
longlong
seconds
=
args
[
0
]
->
val_int
()
;
TIME
ltime
;
longlong
sign
=
1
;
if
((
null_value
=
args
[
0
]
->
null_value
))
if
((
null_value
=
args
[
0
]
->
null_value
))
return
0
;
return
0
;
if
(
seconds
<
0
)
{
sec_to_time
(
args
[
0
]
->
val_int
(),
args
[
0
]
->
unsigned_flag
,
&
ltime
);
seconds
=
-
seconds
;
sign
=
-
1
;
return
(
ltime
.
neg
?
-
1
:
1
)
*
}
((
ltime
.
hour
)
*
10000
+
ltime
.
minute
*
100
+
ltime
.
second
);
return
sign
*
((
seconds
/
3600
)
*
10000
+
((
seconds
/
60
)
%
60
)
*
100
+
(
seconds
%
60
));
}
}
...
@@ -2575,7 +2680,9 @@ String *Item_func_add_time::val_str(String *str)
...
@@ -2575,7 +2680,9 @@ String *Item_func_add_time::val_str(String *str)
}
}
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
l_sign
=
-
l_sign
;
l_sign
=
-
l_sign
;
bzero
((
char
*
)
&
l_time3
,
sizeof
(
l_time3
));
l_time3
.
neg
=
calc_time_diff
(
&
l_time1
,
&
l_time2
,
-
l_sign
,
l_time3
.
neg
=
calc_time_diff
(
&
l_time1
,
&
l_time2
,
-
l_sign
,
&
seconds
,
&
microseconds
);
&
seconds
,
&
microseconds
);
...
@@ -2604,9 +2711,9 @@ String *Item_func_add_time::val_str(String *str)
...
@@ -2604,9 +2711,9 @@ String *Item_func_add_time::val_str(String *str)
}
}
l_time3
.
hour
+=
days
*
24
;
l_time3
.
hour
+=
days
*
24
;
if
(
!
make_datetime
(
l_time1
.
second_part
||
l_time2
.
second_part
?
if
(
!
make_datetime
_with_warn
(
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
,
TIME_MICROSECOND
:
TIME_ONLY
,
&
l_time3
,
str
))
&
l_time3
,
str
))
return
str
;
return
str
;
null_date:
null_date:
...
@@ -2661,6 +2768,8 @@ String *Item_func_timediff::val_str(String *str)
...
@@ -2661,6 +2768,8 @@ String *Item_func_timediff::val_str(String *str)
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
l_sign
=
-
l_sign
;
l_sign
=
-
l_sign
;
bzero
((
char
*
)
&
l_time3
,
sizeof
(
l_time3
));
l_time3
.
neg
=
calc_time_diff
(
&
l_time1
,
&
l_time2
,
l_sign
,
l_time3
.
neg
=
calc_time_diff
(
&
l_time1
,
&
l_time2
,
l_sign
,
&
seconds
,
&
microseconds
);
&
seconds
,
&
microseconds
);
...
@@ -2674,9 +2783,9 @@ String *Item_func_timediff::val_str(String *str)
...
@@ -2674,9 +2783,9 @@ String *Item_func_timediff::val_str(String *str)
calc_time_from_sec
(
&
l_time3
,
(
long
)
seconds
,
microseconds
);
calc_time_from_sec
(
&
l_time3
,
(
long
)
seconds
,
microseconds
);
if
(
!
make_datetime
(
l_time1
.
second_part
||
l_time2
.
second_part
?
if
(
!
make_datetime
_with_warn
(
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
,
TIME_MICROSECOND
:
TIME_ONLY
,
&
l_time3
,
str
))
&
l_time3
,
str
))
return
str
;
return
str
;
null_date:
null_date:
...
@@ -2694,29 +2803,58 @@ String *Item_func_maketime::val_str(String *str)
...
@@ -2694,29 +2803,58 @@ String *Item_func_maketime::val_str(String *str)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
TIME
ltime
;
TIME
ltime
;
bool
overflow
=
0
;
long
hour
=
(
long
)
args
[
0
]
->
val_int
();
long
long
hour
=
args
[
0
]
->
val_int
();
long
minute
=
(
long
)
args
[
1
]
->
val_int
();
long
long
minute
=
args
[
1
]
->
val_int
();
long
second
=
(
long
)
args
[
2
]
->
val_int
();
long
long
second
=
args
[
2
]
->
val_int
();
if
((
null_value
=
(
args
[
0
]
->
null_value
||
if
((
null_value
=
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
args
[
1
]
->
null_value
||
args
[
2
]
->
null_value
||
args
[
2
]
->
null_value
||
minute
>
59
||
minute
<
0
||
minute
<
0
||
minute
>
59
||
second
>
59
||
second
<
0
||
second
<
0
||
second
>
59
||
str
->
alloc
(
19
))))
str
->
alloc
(
19
))))
return
0
;
return
0
;
bzero
((
char
*
)
&
ltime
,
sizeof
(
ltime
));
ltime
.
neg
=
0
;
ltime
.
neg
=
0
;
/* Check for integer overflows */
if
(
hour
<
0
)
if
(
hour
<
0
)
{
{
ltime
.
neg
=
1
;
if
(
args
[
0
]
->
unsigned_flag
)
hour
=
-
hour
;
overflow
=
1
;
else
ltime
.
neg
=
1
;
}
if
(
-
hour
>
UINT_MAX
||
hour
>
UINT_MAX
)
overflow
=
1
;
if
(
!
overflow
)
{
ltime
.
hour
=
(
uint
)
((
hour
<
0
?
-
hour
:
hour
));
ltime
.
minute
=
(
uint
)
minute
;
ltime
.
second
=
(
uint
)
second
;
}
else
{
ltime
.
hour
=
TIME_MAX_HOUR
;
ltime
.
minute
=
TIME_MAX_MINUTE
;
ltime
.
second
=
TIME_MAX_SECOND
;
char
buf
[
28
];
char
*
ptr
=
longlong10_to_str
(
hour
,
buf
,
args
[
0
]
->
unsigned_flag
?
10
:
-
10
);
int
len
=
(
int
)(
ptr
-
buf
)
+
my_sprintf
(
ptr
,
(
ptr
,
":%02u:%02u"
,
(
uint
)
minute
,
(
uint
)
second
));
make_truncated_value_warning
(
current_thd
,
buf
,
len
,
MYSQL_TIMESTAMP_TIME
,
NullS
);
}
if
(
make_time_with_warn
((
DATE_TIME_FORMAT
*
)
0
,
&
ltime
,
str
))
{
null_value
=
1
;
return
0
;
}
}
ltime
.
hour
=
(
ulong
)
hour
;
ltime
.
minute
=
(
ulong
)
minute
;
ltime
.
second
=
(
ulong
)
second
;
make_time
((
DATE_TIME_FORMAT
*
)
0
,
&
ltime
,
str
);
return
str
;
return
str
;
}
}
...
@@ -3060,7 +3198,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
...
@@ -3060,7 +3198,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
goto
null_date
;
goto
null_date
;
null_value
=
0
;
null_value
=
0
;
bzero
((
char
*
)
ltime
,
sizeof
(
ltime
));
bzero
((
char
*
)
ltime
,
sizeof
(
*
ltime
));
date_time_format
.
format
.
str
=
(
char
*
)
format
->
ptr
();
date_time_format
.
format
.
str
=
(
char
*
)
format
->
ptr
();
date_time_format
.
format
.
length
=
format
->
length
();
date_time_format
.
format
.
length
=
format
->
length
();
if
(
extract_date_time
(
&
date_time_format
,
val
->
ptr
(),
val
->
length
(),
if
(
extract_date_time
(
&
date_time_format
,
val
->
ptr
(),
val
->
length
(),
...
...
sql/time.cc
View file @
a82e5d4a
...
@@ -289,9 +289,9 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap)
...
@@ -289,9 +289,9 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap)
bool
bool
str_to_time_with_warn
(
const
char
*
str
,
uint
length
,
TIME
*
l_time
)
str_to_time_with_warn
(
const
char
*
str
,
uint
length
,
TIME
*
l_time
)
{
{
int
wa
s_cut
;
int
wa
rning
;
bool
ret_val
=
str_to_time
(
str
,
length
,
l_time
,
&
wa
s_cut
);
bool
ret_val
=
str_to_time
(
str
,
length
,
l_time
,
&
wa
rning
);
if
(
was_cut
)
if
(
ret_val
||
warning
)
make_truncated_value_warning
(
current_thd
,
str
,
length
,
make_truncated_value_warning
(
current_thd
,
str
,
length
,
MYSQL_TIMESTAMP_TIME
,
NullS
);
MYSQL_TIMESTAMP_TIME
,
NullS
);
return
ret_val
;
return
ret_val
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment