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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
737e13e5
Commit
737e13e5
authored
Oct 11, 2006
by
kaa@polly.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-4.1-maint
into polly.local:/home/kaa/src/maint/m41-maint--07OGk
parents
79f1355b
a050de98
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
425 additions
and
94 deletions
+425
-94
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
-22
sql/field.cc
sql/field.cc
+17
-18
sql/item_timefunc.cc
sql/item_timefunc.cc
+181
-45
sql/time.cc
sql/time.cc
+3
-3
No files found.
include/my_time.h
View file @
737e13e5
...
...
@@ -44,12 +44,24 @@ typedef long my_time_t;
#define TIME_FUZZY_DATE 1
#define TIME_DATETIME_ONLY 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
str_to_datetime
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
uint
flags
,
int
*
was_cut
);
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
);
...
...
mysql-test/r/func_sapdb.result
View file @
737e13e5
...
...
@@ -97,7 +97,9 @@ subtime("02:01:01.999999", "01:01:01.999999")
01:00:00.000000
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")
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");
timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002")
46:58:57.999999
...
...
@@ -208,13 +210,16 @@ NULL NULL
SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test;
ttt qqq
-744:00:00 NULL
26305:01:02
22:58:58
-
26305:01:02
-22:58:58
838:59:59
22:58:58
-
838:59:59
-22:58:58
NULL 26:02:02
00:00:00 -26:02:02
NULL NULL
NULL NULL
00:00:00 -24:00:00
Warnings:
Warning 1292 Truncated incorrect time value: '26305:01:02'
Warning 1292 Truncated incorrect time value: '-26305:01:02'
drop table t1, test;
select addtime("-01:01:01.01", "-23:59:59.1") as a;
a
...
...
@@ -224,7 +229,9 @@ a
10000
select microsecond(19971231235959.01) as 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;
a
1997-12-31 00:00:10.090000
...
...
mysql-test/r/func_time.result
View file @
737e13e5
...
...
@@ -330,7 +330,9 @@ extract(DAY_MINUTE FROM "02 10:11:12")
21011
select 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");
extract(HOUR FROM "1999-01-02 10:11:12")
10
...
...
@@ -694,6 +696,93 @@ t1 CREATE TABLE `t1` (
`from_unixtime(1) + 0` double(23,6) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
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 Data truncated; out of range 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'
SET NAMES latin1;
SET character_set_results = NULL;
SHOW VARIABLES LIKE 'character_set_results';
...
...
mysql-test/t/func_time.test
View file @
737e13e5
...
...
@@ -369,6 +369,47 @@ show create table t1;
drop
table
t1
;
#
# 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
));
# 21913: DATE_FORMAT() Crashes mysql server if I use it through
# mysql-connector-j driver.
#
...
...
sql-common/my_time.c
View file @
737e13e5
...
...
@@ -402,8 +402,10 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
There may be an optional [.second_part] after seconds
length Length of str
l_time Store result here
was_cut Set to 1 if value was cut during conversion or to 0
otherwise.
warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string
was cut during conversion, and/or
MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is
out of range.
NOTES
Because of the extra days argument, this function can only
...
...
@@ -414,16 +416,16 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
1 error
*/
bool
str_to_time
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
int
*
was_cut
)
bool
str_to_time
(
const
char
*
str
,
uint
length
,
MYSQL_TIME
*
l_time
,
int
*
warning
)
{
long
date
[
5
],
value
;
ulong
date
[
5
];
ulonglong
value
;
const
char
*
end
=
str
+
length
,
*
end_of_days
;
bool
found_days
,
found_hours
;
uint
state
;
l_time
->
neg
=
0
;
*
wa
s_cut
=
0
;
*
wa
rning
=
0
;
for
(;
str
!=
end
&&
my_isspace
(
&
my_charset_latin1
,
*
str
)
;
str
++
)
length
--
;
if
(
str
!=
end
&&
*
str
==
'-'
)
...
...
@@ -438,13 +440,16 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
/* Check first if this is a full TIMESTAMP */
if
(
length
>=
12
)
{
/* Probably full timestamp */
int
was_cut
;
enum
enum_mysql_timestamp_type
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
(
was_cut
)
*
warning
|=
MYSQL_TIME_WARN_TRUNCATED
;
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 */
...
...
@@ -524,7 +529,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
if
(
field_length
>
0
)
value
*=
(
long
)
log_10_int
[
field_length
];
else
if
(
field_length
<
0
)
*
wa
s_cut
=
1
;
*
wa
rning
|=
MYSQL_TIME_WARN_TRUNCATED
;
date
[
4
]
=
value
;
}
else
...
...
@@ -538,10 +543,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
((
str
[
1
]
==
'-'
||
str
[
1
]
==
'+'
)
&&
(
end
-
str
)
>
2
&&
my_isdigit
(
&
my_charset_latin1
,
str
[
2
]))))
{
*
was_cut
=
1
;
return
1
;
}
if
(
internal_format_positions
[
7
]
!=
255
)
{
...
...
@@ -560,12 +562,12 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
}
}
/*
Some simple
checks */
if
(
date
[
2
]
>=
60
||
date
[
3
]
>=
60
)
{
*
was_cut
=
1
;
/*
Integer overflow
checks */
if
(
date
[
0
]
>
UINT_MAX
||
date
[
1
]
>
UINT_MAX
||
date
[
2
]
>
UINT_MAX
||
date
[
3
]
>
UINT_MAX
||
date
[
4
]
>
UINT_MAX
)
return
1
;
}
l_time
->
year
=
0
;
/* For protocol::store_time */
l_time
->
month
=
0
;
l_time
->
day
=
date
[
0
];
...
...
@@ -575,6 +577,10 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
l_time
->
second_part
=
date
[
4
];
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 */
if
(
str
!=
end
)
{
...
...
@@ -582,7 +588,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
{
if
(
!
my_isspace
(
&
my_charset_latin1
,
*
str
))
{
*
wa
s_cut
=
1
;
*
wa
rning
|=
MYSQL_TIME_WARN_TRUNCATED
;
break
;
}
}
while
(
++
str
!=
end
);
...
...
@@ -591,6 +597,47 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
}
/*
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.
...
...
@@ -776,7 +823,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
)
{
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
?
"-"
:
""
),
extra_hours
+
l_time
->
hour
,
l_time
->
minute
,
...
...
@@ -785,7 +832,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
)
{
return
my_sprintf
(
to
,
(
to
,
"%04
d-%02d-%02d
"
,
return
my_sprintf
(
to
,
(
to
,
"%04
u-%02u-%02u
"
,
l_time
->
year
,
l_time
->
month
,
l_time
->
day
));
...
...
@@ -793,7 +840,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
)
{
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
->
month
,
l_time
->
day
,
...
...
sql/field.cc
View file @
737e13e5
...
...
@@ -3961,9 +3961,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
{
TIME
ltime
;
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
;
error
=
2
;
...
...
@@ -3972,29 +3973,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
}
else
{
if
(
error
)
if
(
warning
&
MYSQL_TIME_WARN_TRUNCATED
)
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_TRUNCATED
,
from
,
len
,
MYSQL_TIMESTAMP_TIME
,
1
);
if
(
ltime
.
month
)
ltime
.
day
=
0
;
tmp
=
(
ltime
.
day
*
24L
+
ltime
.
hour
)
*
10000L
+
(
ltime
.
minute
*
100
+
ltime
.
second
);
if
(
tmp
>
8385959
)
if
(
warning
&
MYSQL_TIME_WARN_OUT_OF_RANGE
)
{
tmp
=
8385959
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
from
,
len
,
MYSQL_TIMESTAMP_TIME
,
!
error
);
error
=
1
;
}
if
(
ltime
.
month
)
ltime
.
day
=
0
;
tmp
=
(
ltime
.
day
*
24L
+
ltime
.
hour
)
*
10000L
+
(
ltime
.
minute
*
100
+
ltime
.
second
);
if
(
error
>
1
)
error
=
2
;
}
if
(
ltime
.
neg
)
tmp
=
-
tmp
;
error
|=
Field_time
::
store
((
longlong
)
tmp
);
int3store
(
ptr
,
tmp
);
return
error
;
}
...
...
@@ -4003,16 +4002,16 @@ int Field_time::store(double nr)
{
long
tmp
;
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
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
);
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
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
);
error
=
1
;
...
...
@@ -4040,17 +4039,17 @@ int Field_time::store(longlong nr)
{
long
tmp
;
int
error
=
0
;
if
(
nr
>
(
longlong
)
8385959L
)
if
(
nr
>
(
longlong
)
TIME_MAX_VALUE
)
{
tmp
=
8385959L
;
tmp
=
TIME_MAX_VALUE
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
,
1
);
error
=
1
;
}
else
if
(
nr
<
(
longlong
)
-
8385959L
)
else
if
(
nr
<
(
longlong
)
-
TIME_MAX_VALUE
)
{
tmp
=
-
8385959L
;
tmp
=
-
TIME_MAX_VALUE
;
set_datetime_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
nr
,
MYSQL_TIMESTAMP_TIME
,
1
);
...
...
sql/item_timefunc.cc
View file @
737e13e5
...
...
@@ -95,6 +95,124 @@ 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
);
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
);
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
);
return
1
;
}
/*
Date formats corresponding to compound %r and %T conversion specifiers
...
...
@@ -1488,8 +1606,6 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
String
*
Item_func_sec_to_time
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
longlong
seconds
=
(
longlong
)
args
[
0
]
->
val_int
();
uint
sec
;
TIME
ltime
;
if
((
null_value
=
args
[
0
]
->
null_value
)
||
str
->
alloc
(
19
))
...
...
@@ -1498,19 +1614,8 @@ String *Item_func_sec_to_time::val_str(String *str)
return
(
String
*
)
0
;
}
ltime
.
neg
=
0
;
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
;
sec_to_time
(
args
[
0
]
->
val_int
(),
args
[
0
]
->
unsigned_flag
,
&
ltime
);
make_time
((
DATE_TIME_FORMAT
*
)
0
,
&
ltime
,
str
);
return
str
;
}
...
...
@@ -1519,16 +1624,15 @@ String *Item_func_sec_to_time::val_str(String *str)
longlong
Item_func_sec_to_time
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
longlong
seconds
=
args
[
0
]
->
val_int
()
;
longlong
sign
=
1
;
TIME
ltime
;
if
((
null_value
=
args
[
0
]
->
null_value
))
return
0
;
if
(
seconds
<
0
)
{
seconds
=
-
seconds
;
sign
=
-
1
;
}
return
sign
*
((
seconds
/
3600
)
*
10000
+
((
seconds
/
60
)
%
60
)
*
100
+
(
seconds
%
60
));
sec_to_time
(
args
[
0
]
->
val_int
(),
args
[
0
]
->
unsigned_flag
,
&
ltime
);
return
(
ltime
.
neg
?
-
1
:
1
)
*
((
ltime
.
hour
)
*
10000
+
ltime
.
minute
*
100
+
ltime
.
second
);
}
...
...
@@ -2534,7 +2638,9 @@ String *Item_func_add_time::val_str(String *str)
}
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
l_sign
=
-
l_sign
;
bzero
((
char
*
)
&
l_time3
,
sizeof
(
l_time3
));
l_time3
.
neg
=
calc_time_diff
(
&
l_time1
,
&
l_time2
,
-
l_sign
,
&
seconds
,
&
microseconds
);
...
...
@@ -2563,9 +2669,9 @@ String *Item_func_add_time::val_str(String *str)
}
l_time3
.
hour
+=
days
*
24
;
if
(
!
make_datetime
(
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
,
&
l_time3
,
str
))
if
(
!
make_datetime
_with_warn
(
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
,
&
l_time3
,
str
))
return
str
;
null_date:
...
...
@@ -2620,6 +2726,8 @@ String *Item_func_timediff::val_str(String *str)
if
(
l_time1
.
neg
!=
l_time2
.
neg
)
l_sign
=
-
l_sign
;
bzero
((
char
*
)
&
l_time3
,
sizeof
(
l_time3
));
l_time3
.
neg
=
calc_time_diff
(
&
l_time1
,
&
l_time2
,
l_sign
,
&
seconds
,
&
microseconds
);
...
...
@@ -2633,9 +2741,9 @@ String *Item_func_timediff::val_str(String *str)
calc_time_from_sec
(
&
l_time3
,
(
long
)
seconds
,
microseconds
);
if
(
!
make_datetime
(
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
,
&
l_time3
,
str
))
if
(
!
make_datetime
_with_warn
(
l_time1
.
second_part
||
l_time2
.
second_part
?
TIME_MICROSECOND
:
TIME_ONLY
,
&
l_time3
,
str
))
return
str
;
null_date:
...
...
@@ -2653,29 +2761,57 @@ String *Item_func_maketime::val_str(String *str)
{
DBUG_ASSERT
(
fixed
==
1
);
TIME
ltime
;
bool
overflow
=
0
;
long
hour
=
(
long
)
args
[
0
]
->
val_int
();
long
minute
=
(
long
)
args
[
1
]
->
val_int
();
long
second
=
(
long
)
args
[
2
]
->
val_int
();
long
long
hour
=
args
[
0
]
->
val_int
();
long
long
minute
=
args
[
1
]
->
val_int
();
long
long
second
=
args
[
2
]
->
val_int
();
if
((
null_value
=
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
args
[
2
]
->
null_value
||
minute
>
59
||
minute
<
0
||
second
>
59
||
second
<
0
||
str
->
alloc
(
19
))))
args
[
1
]
->
null_value
||
args
[
2
]
->
null_value
||
minute
<
0
||
minute
>
59
||
second
<
0
||
second
>
59
||
str
->
alloc
(
19
))))
return
0
;
bzero
((
char
*
)
&
ltime
,
sizeof
(
ltime
));
ltime
.
neg
=
0
;
/* Check for integer overflows */
if
(
hour
<
0
)
{
ltime
.
neg
=
1
;
hour
=
-
hour
;
if
(
args
[
0
]
->
unsigned_flag
)
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
);
}
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
;
}
...
...
@@ -2881,7 +3017,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date)
goto
null_date
;
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
.
length
=
format
->
length
();
if
(
extract_date_time
(
&
date_time_format
,
val
->
ptr
(),
val
->
length
(),
...
...
sql/time.cc
View file @
737e13e5
...
...
@@ -255,9 +255,9 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *in_dst_time_gap)
bool
str_to_time_with_warn
(
const
char
*
str
,
uint
length
,
TIME
*
l_time
)
{
int
wa
s_cut
;
bool
ret_val
=
str_to_time
(
str
,
length
,
l_time
,
&
wa
s_cut
);
if
(
was_cut
)
int
wa
rning
;
bool
ret_val
=
str_to_time
(
str
,
length
,
l_time
,
&
wa
rning
);
if
(
ret_val
||
warning
)
make_truncated_value_warning
(
current_thd
,
str
,
length
,
MYSQL_TIMESTAMP_TIME
);
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