Commit 0e330318 authored by unknown's avatar unknown

Merge shellback.(none):/home/msvensson/mysql/mysql-5.0-maint

into  shellback.(none):/home/msvensson/mysql/mysql-5.0-maint-new


mysql-test/r/mysql.result:
  Auto merged
mysql-test/t/mysql.test:
  Auto merged
sql/sql_parse.cc:
  Auto merged
parents a4f01a94 04502c3f
...@@ -9,3 +9,4 @@ ...@@ -9,3 +9,4 @@
451ab499rgdjXyOnUDqHu-wBDoS-OQ 451ab499rgdjXyOnUDqHu-wBDoS-OQ
45214442pBGT9KuZEGixBH71jTzbOA 45214442pBGT9KuZEGixBH71jTzbOA
45214a07hVsIGwvwa-WrO-jpeaSwVw 45214a07hVsIGwvwa-WrO-jpeaSwVw
452a92d0-31-8wSzSfZi165fcGcXPA
...@@ -388,6 +388,21 @@ int main(int argc,char *argv[]) ...@@ -388,6 +388,21 @@ int main(int argc,char *argv[])
else else
status.add_to_history=1; status.add_to_history=1;
status.exit_status=1; status.exit_status=1;
{
/*
The file descriptor-layer may be out-of-sync with the file-number layer,
so we make sure that "stdout" is really open. If its file is closed then
explicitly close the FD layer.
*/
int stdout_fileno_copy;
stdout_fileno_copy= dup(fileno(stdout)); /* Okay if fileno fails. */
if (stdout_fileno_copy == -1)
fclose(stdout);
else
close(stdout_fileno_copy); /* Clean up dup(). */
}
load_defaults("my",load_default_groups,&argc,&argv); load_defaults("my",load_default_groups,&argc,&argv);
defaults_argv=argv; defaults_argv=argv;
if (get_options(argc, (char **) argv)) if (get_options(argc, (char **) argv))
......
...@@ -49,6 +49,16 @@ typedef long my_time_t; ...@@ -49,6 +49,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);
...@@ -61,7 +71,9 @@ ulonglong TIME_to_ulonglong(const MYSQL_TIME *time); ...@@ -61,7 +71,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);
......
...@@ -324,7 +324,7 @@ pthread_handler_t thr_find_all_keys(void *arg) ...@@ -324,7 +324,7 @@ pthread_handler_t thr_find_all_keys(void *arg)
if (info->sort_info->got_error) if (info->sort_info->got_error)
goto err; goto err;
if (info->keyinfo->flag && HA_VAR_LENGTH_KEY) if (info->keyinfo->flag & HA_VAR_LENGTH_KEY)
{ {
info->write_keys=write_keys_varlen; info->write_keys=write_keys_varlen;
info->read_to_buffer=read_to_buffer_varlen; info->read_to_buffer=read_to_buffer_varlen;
...@@ -516,7 +516,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -516,7 +516,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
{ {
if (got_error) if (got_error)
continue; continue;
if (sinfo->keyinfo->flag && HA_VAR_LENGTH_KEY) if (sinfo->keyinfo->flag & HA_VAR_LENGTH_KEY)
{ {
sinfo->write_keys=write_keys_varlen; sinfo->write_keys=write_keys_varlen;
sinfo->read_to_buffer=read_to_buffer_varlen; sinfo->read_to_buffer=read_to_buffer_varlen;
......
...@@ -71,3 +71,17 @@ NULL ...@@ -71,3 +71,17 @@ NULL
NULL NULL
NULL NULL
drop table t1; drop table t1;
End of 4.1 tests
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY;
CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY
2006-09-27
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH;
CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH
2006-10-26
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR;
CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR
2007-09-26
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK
2006-10-03
End of 5.0 tests
...@@ -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
......
...@@ -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
...@@ -612,7 +614,7 @@ date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) ...@@ -612,7 +614,7 @@ date_add(date,INTERVAL "1 1:1:1" DAY_SECOND)
2003-01-03 01:01:01 2003-01-03 01:01:01
select date_add(date,INTERVAL "1" WEEK) from t1; select date_add(date,INTERVAL "1" WEEK) from t1;
date_add(date,INTERVAL "1" WEEK) date_add(date,INTERVAL "1" WEEK)
2003-01-09 00:00:00 2003-01-09
select date_add(date,INTERVAL "1" QUARTER) from t1; select date_add(date,INTERVAL "1" QUARTER) from t1;
date_add(date,INTERVAL "1" QUARTER) date_add(date,INTERVAL "1" QUARTER)
2003-04-02 2003-04-02
...@@ -621,7 +623,7 @@ timestampadd(MINUTE, 1, date) ...@@ -621,7 +623,7 @@ timestampadd(MINUTE, 1, date)
2003-01-02 00:01:00 2003-01-02 00:01:00
select timestampadd(WEEK, 1, date) from t1; select timestampadd(WEEK, 1, date) from t1;
timestampadd(WEEK, 1, date) timestampadd(WEEK, 1, date)
2003-01-09 00:00:00 2003-01-09
select timestampadd(SQL_TSI_SECOND, 1, date) from t1; select timestampadd(SQL_TSI_SECOND, 1, date) from t1;
timestampadd(SQL_TSI_SECOND, 1, date) timestampadd(SQL_TSI_SECOND, 1, date)
2003-01-02 00:00:01 2003-01-02 00:00:01
...@@ -890,6 +892,93 @@ t1 CREATE TABLE `t1` ( ...@@ -890,6 +892,93 @@ t1 CREATE TABLE `t1` (
`from_unixtime(1) + 0` double(23,6) default NULL `from_unixtime(1) + 0` double(23,6) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; 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 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'
SET NAMES latin1; SET NAMES latin1;
SET character_set_results = NULL; SET character_set_results = NULL;
SHOW VARIABLES LIKE 'character_set_results'; SHOW VARIABLES LIKE 'character_set_results';
......
...@@ -149,4 +149,17 @@ ERROR at line 1: USE must be followed by a database name ...@@ -149,4 +149,17 @@ ERROR at line 1: USE must be followed by a database name
\\ \\
'; ';
'; ';
create table t17583 (a int);
insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
select count(*) from t17583;
count(*)
1280
drop table t17583;
End of 5.0 tests End of 5.0 tests
...@@ -520,6 +520,7 @@ t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect ...@@ -520,6 +520,7 @@ t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect
show create table t1; show create table t1;
ERROR HY000: Incorrect information in file: './test/t1.frm' ERROR HY000: Incorrect information in file: './test/t1.frm'
drop table t1; drop table t1;
End of 4.1 tests
CREATE TABLE txt1(a int); CREATE TABLE txt1(a int);
CREATE TABLE tyt2(a int); CREATE TABLE tyt2(a int);
CREATE TABLE urkunde(a int); CREATE TABLE urkunde(a int);
...@@ -629,3 +630,4 @@ SHOW TABLES FROM no_such_database; ...@@ -629,3 +630,4 @@ SHOW TABLES FROM no_such_database;
ERROR 42000: Unknown database 'no_such_database' ERROR 42000: Unknown database 'no_such_database'
SHOW COLUMNS FROM no_such_table; SHOW COLUMNS FROM no_such_table;
ERROR 42S02: Table 'test.no_such_table' doesn't exist ERROR 42S02: Table 'test.no_such_table' doesn't exist
End of 5.0 tests
...@@ -64,4 +64,17 @@ insert into t1 values (date_add('2000-01-04', INTERVAL NULL DAY)); ...@@ -64,4 +64,17 @@ insert into t1 values (date_add('2000-01-04', INTERVAL NULL DAY));
select * from t1; select * from t1;
drop table t1; drop table t1;
# End of 4.1 tests --echo End of 4.1 tests
#
# Bug#21811
#
# Make sure we end up with an appropriate
# date format (DATE) after addition operation
#
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY;
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH;
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR;
SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK;
--echo End of 5.0 tests
...@@ -446,6 +446,49 @@ create table t1 select now() - now(), curtime() - curtime(), ...@@ -446,6 +446,49 @@ create table t1 select now() - now(), curtime() - curtime(),
show create table t1; show create table t1;
drop 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 # 21913: DATE_FORMAT() Crashes mysql server if I use it through
# mysql-connector-j driver. # mysql-connector-j driver.
......
...@@ -153,4 +153,21 @@ drop table t1; ...@@ -153,4 +153,21 @@ drop table t1;
--exec echo "SELECT '\';';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql --exec echo "SELECT '\';';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1 --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1
#
# Bug#17583: mysql drops connection when stdout is not writable
#
create table t17583 (a int);
insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
insert into t17583 select a from t17583;
# Close to the minimal data needed to exercise bug.
select count(*) from t17583;
--exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&-
drop table t17583;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -400,7 +400,8 @@ show create table t1; ...@@ -400,7 +400,8 @@ show create table t1;
drop table t1; drop table t1;
# End of 4.1 tests --echo End of 4.1 tests
# #
# BUG 12183 - SHOW OPEN TABLES behavior doesn't match grammar # BUG 12183 - SHOW OPEN TABLES behavior doesn't match grammar
# First we close all open tables with FLUSH tables and then we open some. # First we close all open tables with FLUSH tables and then we open some.
...@@ -506,4 +507,4 @@ SHOW TABLES FROM no_such_database; ...@@ -506,4 +507,4 @@ SHOW TABLES FROM no_such_database;
SHOW COLUMNS FROM no_such_table; SHOW COLUMNS FROM no_such_table;
# End of 5.0 tests. --echo End of 5.0 tests
...@@ -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 *was_cut) int *warning)
{ {
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;
*was_cut= 0; *warning= 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)
*was_cut= 1; *warning|= 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))
{ {
*was_cut= 1; *warning|= 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%02d:%02d:%02d", return my_sprintf(to, (to, "%s%02u:%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, "%04d-%02d-%02d", return my_sprintf(to, (to, "%04u-%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, "%04d-%02d-%02d %02d:%02d:%02d", return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u",
l_time->year, l_time->year,
l_time->month, l_time->month,
l_time->day, l_time->day,
......
...@@ -4762,9 +4762,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -4762,9 +4762,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;
...@@ -4773,29 +4774,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) ...@@ -4773,29 +4774,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;
} }
...@@ -4814,16 +4813,16 @@ int Field_time::store(double nr) ...@@ -4814,16 +4813,16 @@ int Field_time::store(double nr)
{ {
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;
...@@ -4851,17 +4850,17 @@ int Field_time::store(longlong nr, bool unsigned_val) ...@@ -4851,17 +4850,17 @@ int Field_time::store(longlong nr, bool unsigned_val)
{ {
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);
......
...@@ -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
...@@ -1570,8 +1689,6 @@ int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions) ...@@ -1570,8 +1689,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))
...@@ -1580,19 +1697,8 @@ String *Item_func_sec_to_time::val_str(String *str) ...@@ -1580,19 +1697,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;
} }
...@@ -1601,16 +1707,15 @@ String *Item_func_sec_to_time::val_str(String *str) ...@@ -1601,16 +1707,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));
} }
...@@ -2151,11 +2256,15 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const ...@@ -2151,11 +2256,15 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
(date_sub_interval == other->date_sub_interval)); (date_sub_interval == other->date_sub_interval));
} }
/*
'interval_names' reflects the order of the enumeration interval_type.
See item_timefunc.h
*/
static const char *interval_names[]= static const char *interval_names[]=
{ {
"year", "quarter", "month", "day", "hour", "year", "quarter", "month", "week", "day",
"minute", "week", "second", "microsecond", "hour", "minute", "second", "microsecond",
"year_month", "day_hour", "day_minute", "year_month", "day_hour", "day_minute",
"day_second", "hour_minute", "hour_second", "day_second", "hour_minute", "hour_second",
"minute_second", "day_microsecond", "minute_second", "day_microsecond",
...@@ -2692,7 +2801,9 @@ String *Item_func_add_time::val_str(String *str) ...@@ -2692,7 +2801,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);
...@@ -2721,9 +2832,9 @@ String *Item_func_add_time::val_str(String *str) ...@@ -2721,9 +2832,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:
...@@ -2778,6 +2889,8 @@ String *Item_func_timediff::val_str(String *str) ...@@ -2778,6 +2889,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);
...@@ -2791,9 +2904,9 @@ String *Item_func_timediff::val_str(String *str) ...@@ -2791,9 +2904,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:
...@@ -2811,29 +2924,58 @@ String *Item_func_maketime::val_str(String *str) ...@@ -2811,29 +2924,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(); longlong hour= args[0]->val_int();
long minute= (long) args[1]->val_int(); longlong minute= args[1]->val_int();
long second= (long) args[2]->val_int(); longlong 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;
} }
...@@ -3189,7 +3331,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) ...@@ -3189,7 +3331,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(),
......
...@@ -630,18 +630,21 @@ public: ...@@ -630,18 +630,21 @@ public:
}; };
/* /*
The following must be sorted so that simple intervals comes first. 'interval_type' must be sorted so that simple intervals comes first,
(get_interval_value() depends on this) ie year, quarter, month, week, day, hour, etc. The order based on
interval size is also important and the intervals should be kept in a
large to smaller order. (get_interval_value() depends on this)
*/ */
enum interval_type enum interval_type
{ {
INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK,
INTERVAL_MINUTE, INTERVAL_WEEK, INTERVAL_SECOND, INTERVAL_MICROSECOND , INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND,
INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE, INTERVAL_MICROSECOND, INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR,
INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE,
INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND, INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND,
INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND INTERVAL_HOUR_MICROSECOND, INTERVAL_MINUTE_MICROSECOND,
INTERVAL_SECOND_MICROSECOND
}; };
class Item_date_add_interval :public Item_date_func class Item_date_add_interval :public Item_date_func
......
...@@ -254,9 +254,9 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, my_bool *in_dst_time_gap) ...@@ -254,9 +254,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 was_cut; int warning;
bool ret_val= str_to_time(str, length, l_time, &was_cut); bool ret_val= str_to_time(str, length, l_time, &warning);
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment