Merging temporal literals
added: mysql-test/r/temporal_literal.result mysql-test/t/temporal_literal.test modified: client/mysqlbinlog.cc include/my_time.h mysql-test/r/cast.result mysql-test/r/partition_innodb.result mysql-test/t/cast.test mysql-test/t/partition_innodb.test sql-common/my_time.c sql/field.cc sql/item.cc sql/item.h sql/item_cmpfunc.cc sql/item_create.cc sql/item_create.h sql/item_strfunc.cc sql/item_timefunc.cc sql/item_timefunc.h sql/sql_select.cc sql/sql_time.cc sql/sql_time.h sql/sql_yacc.yy storage/spider/spd_db_mysql.cc pending merges: Alexander Barkov 2013-07-10 Adding support for the SQL-standard temporal...
This commit is contained in:
commit
a057b50490
@ -1542,13 +1542,14 @@ the mysql command line client.\n\n");
|
|||||||
|
|
||||||
static my_time_t convert_str_to_timestamp(const char* str)
|
static my_time_t convert_str_to_timestamp(const char* str)
|
||||||
{
|
{
|
||||||
int was_cut;
|
MYSQL_TIME_STATUS status;
|
||||||
MYSQL_TIME l_time;
|
MYSQL_TIME l_time;
|
||||||
long dummy_my_timezone;
|
long dummy_my_timezone;
|
||||||
uint dummy_in_dst_time_gap;
|
uint dummy_in_dst_time_gap;
|
||||||
|
|
||||||
/* We require a total specification (date AND time) */
|
/* We require a total specification (date AND time) */
|
||||||
if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &was_cut) !=
|
if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &status) ||
|
||||||
MYSQL_TIMESTAMP_DATETIME || was_cut)
|
l_time.time_type != MYSQL_TIMESTAMP_DATETIME || status.warnings)
|
||||||
{
|
{
|
||||||
error("Incorrect date and time argument: %s", str);
|
error("Incorrect date and time argument: %s", str);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -78,14 +78,27 @@ extern uchar days_in_month[];
|
|||||||
#define TIME_MAX_VALUE_SECONDS (TIME_MAX_HOUR * 3600L + \
|
#define TIME_MAX_VALUE_SECONDS (TIME_MAX_HOUR * 3600L + \
|
||||||
TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
|
TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Structure to return status from
|
||||||
|
str_to_datetime(), str_to_time().
|
||||||
|
*/
|
||||||
|
typedef struct st_mysql_time_status
|
||||||
|
{
|
||||||
|
int warnings;
|
||||||
|
uint precision;
|
||||||
|
} MYSQL_TIME_STATUS;
|
||||||
|
|
||||||
|
static inline void my_time_status_init(MYSQL_TIME_STATUS *status)
|
||||||
|
{
|
||||||
|
status->warnings= status->precision= 0;
|
||||||
|
}
|
||||||
|
|
||||||
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
|
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
|
||||||
ulonglong flags, int *was_cut);
|
ulonglong flags, int *was_cut);
|
||||||
enum enum_mysql_timestamp_type
|
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
||||||
str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
ulonglong flag, MYSQL_TIME_STATUS *status);
|
||||||
ulonglong flag, int *warning);
|
my_bool str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
||||||
enum enum_mysql_timestamp_type
|
ulonglong flags, MYSQL_TIME_STATUS *status);
|
||||||
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
|
||||||
ulonglong flags, int *was_cut);
|
|
||||||
longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
|
longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
|
||||||
ulonglong flags, int *was_cut);
|
ulonglong flags, int *was_cut);
|
||||||
|
|
||||||
@ -107,7 +120,7 @@ ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
|
|||||||
ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
|
ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
|
||||||
double TIME_to_double(const MYSQL_TIME *my_time);
|
double TIME_to_double(const MYSQL_TIME *my_time);
|
||||||
|
|
||||||
longlong pack_time(MYSQL_TIME *my_time);
|
longlong pack_time(const MYSQL_TIME *my_time);
|
||||||
MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time);
|
MYSQL_TIME *unpack_time(longlong packed, MYSQL_TIME *my_time);
|
||||||
|
|
||||||
int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning);
|
int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning);
|
||||||
|
@ -180,24 +180,24 @@ select 10.0+'10';
|
|||||||
select 10E+0+'10';
|
select 10E+0+'10';
|
||||||
10E+0+'10'
|
10E+0+'10'
|
||||||
20
|
20
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33" USING latin1);
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33" USING latin1);
|
||||||
CONVERT(DATE "2004-01-22 21:45:33" USING latin1)
|
CONVERT(TIMESTAMP "2004-01-22 21:45:33" USING latin1)
|
||||||
2004-01-22 21:45:33
|
2004-01-22 21:45:33
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33",CHAR);
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33",CHAR);
|
||||||
CONVERT(DATE "2004-01-22 21:45:33",CHAR)
|
CONVERT(TIMESTAMP "2004-01-22 21:45:33",CHAR)
|
||||||
2004-01-22 21:45:33
|
2004-01-22 21:45:33
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4));
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33",CHAR(4));
|
||||||
CONVERT(DATE "2004-01-22 21:45:33",CHAR(4))
|
CONVERT(TIMESTAMP "2004-01-22 21:45:33",CHAR(4))
|
||||||
2004
|
2004
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect CHAR(4) value: '2004-01-22 21:45:33'
|
Warning 1292 Truncated incorrect CHAR(4) value: '2004-01-22 21:45:33'
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33",BINARY(4));
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33",BINARY(4));
|
||||||
CONVERT(DATE "2004-01-22 21:45:33",BINARY(4))
|
CONVERT(TIMESTAMP "2004-01-22 21:45:33",BINARY(4))
|
||||||
2004
|
2004
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect BINARY(4) value: '2004-01-22 21:45:33'
|
Warning 1292 Truncated incorrect BINARY(4) value: '2004-01-22 21:45:33'
|
||||||
select CAST(DATE "2004-01-22 21:45:33" AS BINARY(4));
|
select CAST(TIMESTAMP "2004-01-22 21:45:33" AS BINARY(4));
|
||||||
CAST(DATE "2004-01-22 21:45:33" AS BINARY(4))
|
CAST(TIMESTAMP "2004-01-22 21:45:33" AS BINARY(4))
|
||||||
2004
|
2004
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect BINARY(4) value: '2004-01-22 21:45:33'
|
Warning 1292 Truncated incorrect BINARY(4) value: '2004-01-22 21:45:33'
|
||||||
|
@ -51,8 +51,8 @@ p200912 0
|
|||||||
p201103 1
|
p201103 1
|
||||||
p201912 0
|
p201912 0
|
||||||
SELECT count(*) FROM t1 p where c3 in
|
SELECT count(*) FROM t1 p where c3 in
|
||||||
(select c3 from t1 t where t.c3 < date '2011-04-26 19:19:44'
|
(select c3 from t1 t where t.c3 < timestamp '2011-04-26 19:19:44'
|
||||||
and t.c3 > date '2011-04-26 19:18:44') ;
|
and t.c3 > timestamp '2011-04-26 19:18:44') ;
|
||||||
count(*)
|
count(*)
|
||||||
0
|
0
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
418
mysql-test/r/temporal_literal.result
Normal file
418
mysql-test/r/temporal_literal.result
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
SET NAMES latin1;
|
||||||
|
#
|
||||||
|
# Testing DATE literals
|
||||||
|
#
|
||||||
|
SELECT DATE'xxxx';
|
||||||
|
ERROR HY000: Incorrect DATE value: 'xxxx'
|
||||||
|
SELECT DATE'01';
|
||||||
|
ERROR HY000: Incorrect DATE value: '01'
|
||||||
|
SELECT DATE'01-01';
|
||||||
|
ERROR HY000: Incorrect DATE value: '01-01'
|
||||||
|
SELECT DATE'2001';
|
||||||
|
ERROR HY000: Incorrect DATE value: '2001'
|
||||||
|
SELECT DATE'2001-01';
|
||||||
|
ERROR HY000: Incorrect DATE value: '2001-01'
|
||||||
|
SELECT DATE'2001-00-00';
|
||||||
|
DATE'2001-00-00'
|
||||||
|
2001-00-00
|
||||||
|
SELECT DATE'2001-01-00';
|
||||||
|
DATE'2001-01-00'
|
||||||
|
2001-01-00
|
||||||
|
SELECT DATE'0000-00-00';
|
||||||
|
DATE'0000-00-00'
|
||||||
|
0000-00-00
|
||||||
|
SELECT DATE'2001-01-01 00:00:00';
|
||||||
|
ERROR HY000: Incorrect DATE value: '2001-01-01 00:00:00'
|
||||||
|
SELECT DATE'01:01:01';
|
||||||
|
DATE'01:01:01'
|
||||||
|
2001-01-01
|
||||||
|
SELECT DATE'01-01-01';
|
||||||
|
DATE'01-01-01'
|
||||||
|
2001-01-01
|
||||||
|
SELECT DATE'2010-01-01';
|
||||||
|
DATE'2010-01-01'
|
||||||
|
2010-01-01
|
||||||
|
SELECT DATE '2010-01-01';
|
||||||
|
DATE '2010-01-01'
|
||||||
|
2010-01-01
|
||||||
|
CREATE TABLE t1 AS SELECT DATE'2010-01-01';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`DATE'2010-01-01'` date NOT NULL DEFAULT '0000-00-00'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
{d'2001-01-01'},
|
||||||
|
{ d '2001-01-01' },
|
||||||
|
{d'2001-01-01 10:10:10'};
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`{d'2001-01-01'}` date NOT NULL DEFAULT '0000-00-00',
|
||||||
|
`{ d '2001-01-01' }` date NOT NULL DEFAULT '0000-00-00',
|
||||||
|
`2001-01-01 10:10:10` varchar(19) NOT NULL DEFAULT ''
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXPLAIN EXTENDED SELECT {d'2010-01-01'};
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select DATE'2010-01-01' AS `{d'2010-01-01'}`
|
||||||
|
EXPLAIN EXTENDED SELECT DATE'2010-01-01';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select DATE'2010-01-01' AS `DATE'2010-01-01'`
|
||||||
|
#
|
||||||
|
# Testing DATE literals in non-default sql_mode
|
||||||
|
#
|
||||||
|
SET sql_mode=no_zero_in_date;
|
||||||
|
SELECT DATE'2001-00-00';
|
||||||
|
ERROR HY000: Incorrect DATE value: '2001-00-00'
|
||||||
|
SELECT DATE'2001-01-00';
|
||||||
|
ERROR HY000: Incorrect DATE value: '2001-01-00'
|
||||||
|
SELECT DATE'0000-00-00';
|
||||||
|
DATE'0000-00-00'
|
||||||
|
0000-00-00
|
||||||
|
SET sql_mode=no_zero_date;
|
||||||
|
SELECT DATE'0000-00-00';
|
||||||
|
ERROR HY000: Incorrect DATE value: '0000-00-00'
|
||||||
|
SET sql_mode=default;
|
||||||
|
#
|
||||||
|
# Testing TIME literals
|
||||||
|
#
|
||||||
|
SELECT TIME'xxxx';
|
||||||
|
ERROR HY000: Incorrect TIME value: 'xxxx'
|
||||||
|
SELECT TIME'900:00:00';
|
||||||
|
ERROR HY000: Incorrect TIME value: '900:00:00'
|
||||||
|
SELECT TIME'-900:00:00';
|
||||||
|
ERROR HY000: Incorrect TIME value: '-900:00:00'
|
||||||
|
SELECT TIME'1 24:00:00';
|
||||||
|
TIME'1 24:00:00'
|
||||||
|
48:00:00
|
||||||
|
SELECT TIME'30 24:00:00';
|
||||||
|
TIME'30 24:00:00'
|
||||||
|
744:00:00
|
||||||
|
SELECT TIME'0000-00-00 00:00:00';
|
||||||
|
ERROR HY000: Incorrect TIME value: '0000-00-00 00:00:00'
|
||||||
|
SELECT TIME'40 24:00:00';
|
||||||
|
ERROR HY000: Incorrect TIME value: '40 24:00:00'
|
||||||
|
SELECT TIME'10';
|
||||||
|
TIME'10'
|
||||||
|
00:00:10
|
||||||
|
SELECT TIME'10:10';
|
||||||
|
TIME'10:10'
|
||||||
|
10:10:00
|
||||||
|
SELECT TIME'10:11.12';
|
||||||
|
TIME'10:11.12'
|
||||||
|
10:11:00.12
|
||||||
|
SELECT TIME'10:10:10';
|
||||||
|
TIME'10:10:10'
|
||||||
|
10:10:10
|
||||||
|
SELECT TIME'10:10:10.';
|
||||||
|
TIME'10:10:10.'
|
||||||
|
10:10:10
|
||||||
|
SELECT TIME'10:10:10.1';
|
||||||
|
TIME'10:10:10.1'
|
||||||
|
10:10:10.1
|
||||||
|
SELECT TIME'10:10:10.12';
|
||||||
|
TIME'10:10:10.12'
|
||||||
|
10:10:10.12
|
||||||
|
SELECT TIME'10:10:10.123';
|
||||||
|
TIME'10:10:10.123'
|
||||||
|
10:10:10.123
|
||||||
|
SELECT TIME'10:10:10.1234';
|
||||||
|
TIME'10:10:10.1234'
|
||||||
|
10:10:10.1234
|
||||||
|
SELECT TIME'10:10:10.12345';
|
||||||
|
TIME'10:10:10.12345'
|
||||||
|
10:10:10.12345
|
||||||
|
SELECT TIME'10:10:10.123456';
|
||||||
|
TIME'10:10:10.123456'
|
||||||
|
10:10:10.123456
|
||||||
|
SELECT TIME'-10:00:00';
|
||||||
|
TIME'-10:00:00'
|
||||||
|
-10:00:00
|
||||||
|
SELECT TIME '10:11:12';
|
||||||
|
TIME '10:11:12'
|
||||||
|
10:11:12
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
TIME'10:10:10',
|
||||||
|
TIME'10:10:10.',
|
||||||
|
TIME'10:10:10.1',
|
||||||
|
TIME'10:10:10.12',
|
||||||
|
TIME'10:10:10.123',
|
||||||
|
TIME'10:10:10.1234',
|
||||||
|
TIME'10:10:10.12345',
|
||||||
|
TIME'10:10:10.123456';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`TIME'10:10:10'` time NOT NULL DEFAULT '00:00:00',
|
||||||
|
`TIME'10:10:10.'` time NOT NULL DEFAULT '00:00:00',
|
||||||
|
`TIME'10:10:10.1'` time(1) NOT NULL DEFAULT '00:00:00.0',
|
||||||
|
`TIME'10:10:10.12'` time(2) NOT NULL DEFAULT '00:00:00.00',
|
||||||
|
`TIME'10:10:10.123'` time(3) NOT NULL DEFAULT '00:00:00.000',
|
||||||
|
`TIME'10:10:10.1234'` time(4) NOT NULL DEFAULT '00:00:00.0000',
|
||||||
|
`TIME'10:10:10.12345'` time(5) NOT NULL DEFAULT '00:00:00.00000',
|
||||||
|
`TIME'10:10:10.123456'` time(6) NOT NULL DEFAULT '00:00:00.000000'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
{t'10:10:10'},
|
||||||
|
{ t '10:10:10' },
|
||||||
|
{t'10:10:10.'},
|
||||||
|
{t'10:10:10.123456'},
|
||||||
|
{t'2001-01-01'};
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`{t'10:10:10'}` time NOT NULL DEFAULT '00:00:00',
|
||||||
|
`{ t '10:10:10' }` time NOT NULL DEFAULT '00:00:00',
|
||||||
|
`{t'10:10:10.'}` time NOT NULL DEFAULT '00:00:00',
|
||||||
|
`{t'10:10:10.123456'}` time(6) NOT NULL DEFAULT '00:00:00.000000',
|
||||||
|
`2001-01-01` varchar(10) NOT NULL DEFAULT ''
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXPLAIN EXTENDED SELECT {t'10:01:01'};
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select TIME'10:01:01' AS `{t'10:01:01'}`
|
||||||
|
EXPLAIN EXTENDED SELECT TIME'10:01:01';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select TIME'10:01:01' AS `TIME'10:01:01'`
|
||||||
|
#
|
||||||
|
# Testing TIMESTAMP literals
|
||||||
|
#
|
||||||
|
SELECT TIMESTAMP'xxxx';
|
||||||
|
ERROR HY000: Incorrect DATETIME value: 'xxxx'
|
||||||
|
SELECT TIMESTAMP'2010';
|
||||||
|
ERROR HY000: Incorrect DATETIME value: '2010'
|
||||||
|
SELECT TIMESTAMP'2010-01';
|
||||||
|
ERROR HY000: Incorrect DATETIME value: '2010-01'
|
||||||
|
SELECT TIMESTAMP'2010-01-01';
|
||||||
|
ERROR HY000: Incorrect DATETIME value: '2010-01-01'
|
||||||
|
SELECT TIMESTAMP'2010-01-01 00';
|
||||||
|
TIMESTAMP'2010-01-01 00'
|
||||||
|
2010-01-01 00:00:00
|
||||||
|
SELECT TIMESTAMP'2010-01-01 00:01';
|
||||||
|
TIMESTAMP'2010-01-01 00:01'
|
||||||
|
2010-01-01 00:01:00
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10'
|
||||||
|
2010-01-01 10:10:10
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.'
|
||||||
|
2010-01-01 10:10:10
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.1';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.1'
|
||||||
|
2010-01-01 10:10:10.1
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.12';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.12'
|
||||||
|
2010-01-01 10:10:10.12
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.123';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.123'
|
||||||
|
2010-01-01 10:10:10.123
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.1234';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.1234'
|
||||||
|
2010-01-01 10:10:10.1234
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.12345';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.12345'
|
||||||
|
2010-01-01 10:10:10.12345
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.123456';
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.123456'
|
||||||
|
2010-01-01 10:10:10.123456
|
||||||
|
SELECT TIMESTAMP '2010-01-01 10:20:30';
|
||||||
|
TIMESTAMP '2010-01-01 10:20:30'
|
||||||
|
2010-01-01 10:20:30
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.1',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.12',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.123',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.1234',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.12345',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.123456';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10'` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10.'` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10.1'` datetime(1) NOT NULL DEFAULT '0000-00-00 00:00:00.0',
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10.12'` datetime(2) NOT NULL DEFAULT '0000-00-00 00:00:00.00',
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10.123'` datetime(3) NOT NULL DEFAULT '0000-00-00 00:00:00.000',
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10.1234'` datetime(4) NOT NULL DEFAULT '0000-00-00 00:00:00.0000',
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10.12345'` datetime(5) NOT NULL DEFAULT '0000-00-00 00:00:00.00000',
|
||||||
|
`TIMESTAMP'2010-01-01 10:10:10.123456'` datetime(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
{ts'2001-01-01 10:10:10'},
|
||||||
|
{ ts '2001-01-01 10:10:10' },
|
||||||
|
{ts'2001-01-01 10:10:10.'},
|
||||||
|
{ts'2001-01-01 10:10:10.123456'},
|
||||||
|
{ts'2001-01-01'};
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`{ts'2001-01-01 10:10:10'}` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
|
`{ ts '2001-01-01 10:10:10' }` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
|
`{ts'2001-01-01 10:10:10.'}` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
|
`{ts'2001-01-01 10:10:10.123456'}` datetime(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
|
||||||
|
`2001-01-01` varchar(10) NOT NULL DEFAULT ''
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXPLAIN EXTENDED SELECT {ts'2010-01-01 10:10:10'};
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select TIMESTAMP'2010-01-01 10:10:10' AS `{ts'2010-01-01 10:10:10'}`
|
||||||
|
EXPLAIN EXTENDED SELECT TIMESTAMP'2010-01-01 10:10:10';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select TIMESTAMP'2010-01-01 10:10:10' AS `TIMESTAMP'2010-01-01 10:10:10'`
|
||||||
|
#
|
||||||
|
# Testing nanosecond rounding for TIMESTAMP literals with bad dates
|
||||||
|
#
|
||||||
|
SELECT TIMESTAMP'2001-00-00 00:00:00.999999';
|
||||||
|
TIMESTAMP'2001-00-00 00:00:00.999999'
|
||||||
|
2001-00-00 00:00:00.999999
|
||||||
|
SELECT TIMESTAMP'2001-00-01 00:00:00.999999';
|
||||||
|
TIMESTAMP'2001-00-01 00:00:00.999999'
|
||||||
|
2001-00-01 00:00:00.999999
|
||||||
|
SELECT TIMESTAMP'2001-01-00 00:00:00.999999';
|
||||||
|
TIMESTAMP'2001-01-00 00:00:00.999999'
|
||||||
|
2001-01-00 00:00:00.999999
|
||||||
|
SELECT TIMESTAMP'2001-00-00 00:00:00.9999999';
|
||||||
|
ERROR HY000: Incorrect DATETIME value: '2001-00-00 00:00:00.9999999'
|
||||||
|
SELECT TIMESTAMP'2001-00-01 00:00:00.9999999';
|
||||||
|
ERROR HY000: Incorrect DATETIME value: '2001-00-01 00:00:00.9999999'
|
||||||
|
SELECT TIMESTAMP'2001-01-00 00:00:00.9999999';
|
||||||
|
ERROR HY000: Incorrect DATETIME value: '2001-01-00 00:00:00.9999999'
|
||||||
|
#
|
||||||
|
# String literal with bad dates and nanoseconds to DATETIME(N)
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATETIME(6));
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-00 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-01 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-00 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
2001-00-00 00:00:00.999999
|
||||||
|
2001-00-01 00:00:00.999999
|
||||||
|
2001-01-00 00:00:00.999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATETIME(5));
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-00 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-01 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-00 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
2001-00-00 00:00:00.99999
|
||||||
|
2001-00-01 00:00:00.99999
|
||||||
|
2001-01-00 00:00:00.99999
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-00 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-01 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-00 00:00:00.9999999');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
2001-00-00 00:00:00
|
||||||
|
2001-00-01 00:00:00
|
||||||
|
2001-01-00 00:00:00
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Testing Item_date_literal::eq
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATE);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01'),('2003-01-01');
|
||||||
|
SELECT * FROM t1 WHERE a BETWEEN DATE'2001-01-01' AND DATE'2002-01-01';
|
||||||
|
a
|
||||||
|
2001-01-01
|
||||||
|
SELECT DATE'2001-01-01' FROM t1 GROUP BY DATE'2001-01-01';
|
||||||
|
DATE'2001-01-01'
|
||||||
|
2001-01-01
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# TIME literals in no-zero date context
|
||||||
|
#
|
||||||
|
SELECT TO_DAYS(TIME'00:00:00');
|
||||||
|
TO_DAYS(TIME'00:00:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT TO_SECONDS(TIME'00:00:00');
|
||||||
|
TO_SECONDS(TIME'00:00:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT DAYOFYEAR(TIME'00:00:00');
|
||||||
|
DAYOFYEAR(TIME'00:00:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT WEEK(TIME'00:00:00');
|
||||||
|
WEEK(TIME'00:00:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT YEARWEEK(TIME'00:00:00');
|
||||||
|
YEARWEEK(TIME'00:00:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT WEEKDAY(TIME'00:00:00');
|
||||||
|
WEEKDAY(TIME'00:00:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT CONVERT_TZ(TIME'00:00:00','+00:00','+01:00');
|
||||||
|
CONVERT_TZ(TIME'00:00:00','+00:00','+01:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT DATE_ADD(TIME'00:00:00', INTERVAL 1 HOUR);
|
||||||
|
DATE_ADD(TIME'00:00:00', INTERVAL 1 HOUR)
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
SELECT TIMESTAMPDIFF(SECOND,TIME'00:00:00', TIME'00:00:00');
|
||||||
|
TIMESTAMPDIFF(SECOND,TIME'00:00:00', TIME'00:00:00')
|
||||||
|
NULL
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '00:00:00'
|
||||||
|
#
|
||||||
|
# Testing Item_func::fix_fields()
|
||||||
|
#
|
||||||
|
SELECT 'a' LIKE 'a' ESCAPE DATE'2001-01-01';
|
||||||
|
ERROR HY000: Incorrect arguments to ESCAPE
|
||||||
|
SELECT 'a' LIKE 'a' ESCAPE TIMESTAMP'2001-01-01 00:00:00';
|
||||||
|
ERROR HY000: Incorrect arguments to ESCAPE
|
||||||
|
SELECT 'a' LIKE 'a' ESCAPE TIME'00:00:00';
|
||||||
|
ERROR HY000: Incorrect arguments to ESCAPE
|
@ -74,11 +74,11 @@ select 10E+0+'10';
|
|||||||
|
|
||||||
# The following cast creates warnings
|
# The following cast creates warnings
|
||||||
|
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33" USING latin1);
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33" USING latin1);
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33",CHAR);
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33",CHAR);
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33",CHAR(4));
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33",CHAR(4));
|
||||||
select CONVERT(DATE "2004-01-22 21:45:33",BINARY(4));
|
select CONVERT(TIMESTAMP "2004-01-22 21:45:33",BINARY(4));
|
||||||
select CAST(DATE "2004-01-22 21:45:33" AS BINARY(4));
|
select CAST(TIMESTAMP "2004-01-22 21:45:33" AS BINARY(4));
|
||||||
select CAST(0xb3 as signed);
|
select CAST(0xb3 as signed);
|
||||||
select CAST(0x8fffffffffffffff as signed);
|
select CAST(0x8fffffffffffffff as signed);
|
||||||
select CAST(0xffffffffffffffff as unsigned);
|
select CAST(0xffffffffffffffff as unsigned);
|
||||||
|
@ -60,8 +60,8 @@ insert into t1(c2,c3) values ("Test row",'2010-01-01 00:00:00');
|
|||||||
|
|
||||||
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test';
|
SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1' AND TABLE_SCHEMA = 'test';
|
||||||
SELECT count(*) FROM t1 p where c3 in
|
SELECT count(*) FROM t1 p where c3 in
|
||||||
(select c3 from t1 t where t.c3 < date '2011-04-26 19:19:44'
|
(select c3 from t1 t where t.c3 < timestamp '2011-04-26 19:19:44'
|
||||||
and t.c3 > date '2011-04-26 19:18:44') ;
|
and t.c3 > timestamp '2011-04-26 19:18:44') ;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
217
mysql-test/t/temporal_literal.test
Normal file
217
mysql-test/t/temporal_literal.test
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
SET NAMES latin1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing DATE literals
|
||||||
|
--echo #
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'xxxx';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'01';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'01-01';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'2001';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'2001-01';
|
||||||
|
SELECT DATE'2001-00-00';
|
||||||
|
SELECT DATE'2001-01-00';
|
||||||
|
SELECT DATE'0000-00-00';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'2001-01-01 00:00:00';
|
||||||
|
SELECT DATE'01:01:01';
|
||||||
|
SELECT DATE'01-01-01';
|
||||||
|
SELECT DATE'2010-01-01';
|
||||||
|
SELECT DATE '2010-01-01';
|
||||||
|
CREATE TABLE t1 AS SELECT DATE'2010-01-01';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
{d'2001-01-01'},
|
||||||
|
{ d '2001-01-01' },
|
||||||
|
{d'2001-01-01 10:10:10'};
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXPLAIN EXTENDED SELECT {d'2010-01-01'};
|
||||||
|
EXPLAIN EXTENDED SELECT DATE'2010-01-01';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing DATE literals in non-default sql_mode
|
||||||
|
--echo #
|
||||||
|
SET sql_mode=no_zero_in_date;
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'2001-00-00';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'2001-01-00';
|
||||||
|
SELECT DATE'0000-00-00';
|
||||||
|
|
||||||
|
SET sql_mode=no_zero_date;
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT DATE'0000-00-00';
|
||||||
|
SET sql_mode=default;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing TIME literals
|
||||||
|
--echo #
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'xxxx';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'900:00:00';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'-900:00:00';
|
||||||
|
SELECT TIME'1 24:00:00';
|
||||||
|
SELECT TIME'30 24:00:00';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'0000-00-00 00:00:00';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'40 24:00:00';
|
||||||
|
SELECT TIME'10';
|
||||||
|
SELECT TIME'10:10';
|
||||||
|
SELECT TIME'10:11.12';
|
||||||
|
SELECT TIME'10:10:10';
|
||||||
|
SELECT TIME'10:10:10.';
|
||||||
|
SELECT TIME'10:10:10.1';
|
||||||
|
SELECT TIME'10:10:10.12';
|
||||||
|
SELECT TIME'10:10:10.123';
|
||||||
|
SELECT TIME'10:10:10.1234';
|
||||||
|
SELECT TIME'10:10:10.12345';
|
||||||
|
SELECT TIME'10:10:10.123456';
|
||||||
|
SELECT TIME'-10:00:00';
|
||||||
|
SELECT TIME '10:11:12';
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
TIME'10:10:10',
|
||||||
|
TIME'10:10:10.',
|
||||||
|
TIME'10:10:10.1',
|
||||||
|
TIME'10:10:10.12',
|
||||||
|
TIME'10:10:10.123',
|
||||||
|
TIME'10:10:10.1234',
|
||||||
|
TIME'10:10:10.12345',
|
||||||
|
TIME'10:10:10.123456';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
{t'10:10:10'},
|
||||||
|
{ t '10:10:10' },
|
||||||
|
{t'10:10:10.'},
|
||||||
|
{t'10:10:10.123456'},
|
||||||
|
{t'2001-01-01'};
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXPLAIN EXTENDED SELECT {t'10:01:01'};
|
||||||
|
EXPLAIN EXTENDED SELECT TIME'10:01:01';
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing TIMESTAMP literals
|
||||||
|
--echo #
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIMESTAMP'xxxx';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIMESTAMP'2010';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIMESTAMP'2010-01';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIMESTAMP'2010-01-01';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 00';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 00:01';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.1';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.12';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.123';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.1234';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.12345';
|
||||||
|
SELECT TIMESTAMP'2010-01-01 10:10:10.123456';
|
||||||
|
SELECT TIMESTAMP '2010-01-01 10:20:30';
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.1',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.12',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.123',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.1234',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.12345',
|
||||||
|
TIMESTAMP'2010-01-01 10:10:10.123456';
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 AS SELECT
|
||||||
|
{ts'2001-01-01 10:10:10'},
|
||||||
|
{ ts '2001-01-01 10:10:10' },
|
||||||
|
{ts'2001-01-01 10:10:10.'},
|
||||||
|
{ts'2001-01-01 10:10:10.123456'},
|
||||||
|
{ts'2001-01-01'};
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
EXPLAIN EXTENDED SELECT {ts'2010-01-01 10:10:10'};
|
||||||
|
EXPLAIN EXTENDED SELECT TIMESTAMP'2010-01-01 10:10:10';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing nanosecond rounding for TIMESTAMP literals with bad dates
|
||||||
|
--echo #
|
||||||
|
SELECT TIMESTAMP'2001-00-00 00:00:00.999999';
|
||||||
|
SELECT TIMESTAMP'2001-00-01 00:00:00.999999';
|
||||||
|
SELECT TIMESTAMP'2001-01-00 00:00:00.999999';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIMESTAMP'2001-00-00 00:00:00.9999999';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIMESTAMP'2001-00-01 00:00:00.9999999';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIMESTAMP'2001-01-00 00:00:00.9999999';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # String literal with bad dates and nanoseconds to DATETIME(N)
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a DATETIME(6));
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-00 00:00:00.9999999');
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-01 00:00:00.9999999');
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-00 00:00:00.9999999');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATETIME(5));
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-00 00:00:00.9999999');
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-01 00:00:00.9999999');
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-00 00:00:00.9999999');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATETIME);
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-00 00:00:00.9999999');
|
||||||
|
INSERT INTO t1 VALUES ('2001-00-01 00:00:00.9999999');
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-00 00:00:00.9999999');
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing Item_date_literal::eq
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a DATE);
|
||||||
|
INSERT INTO t1 VALUES ('2001-01-01'),('2003-01-01');
|
||||||
|
SELECT * FROM t1 WHERE a BETWEEN DATE'2001-01-01' AND DATE'2002-01-01';
|
||||||
|
SELECT DATE'2001-01-01' FROM t1 GROUP BY DATE'2001-01-01';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # TIME literals in no-zero date context
|
||||||
|
--echo #
|
||||||
|
SELECT TO_DAYS(TIME'00:00:00');
|
||||||
|
SELECT TO_SECONDS(TIME'00:00:00');
|
||||||
|
SELECT DAYOFYEAR(TIME'00:00:00');
|
||||||
|
SELECT WEEK(TIME'00:00:00');
|
||||||
|
SELECT YEARWEEK(TIME'00:00:00');
|
||||||
|
SELECT WEEKDAY(TIME'00:00:00');
|
||||||
|
SELECT CONVERT_TZ(TIME'00:00:00','+00:00','+01:00');
|
||||||
|
SELECT DATE_ADD(TIME'00:00:00', INTERVAL 1 HOUR);
|
||||||
|
SELECT TIMESTAMPDIFF(SECOND,TIME'00:00:00', TIME'00:00:00');
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Testing Item_func::fix_fields()
|
||||||
|
--echo #
|
||||||
|
--error ER_WRONG_ARGUMENTS
|
||||||
|
SELECT 'a' LIKE 'a' ESCAPE DATE'2001-01-01';
|
||||||
|
--error ER_WRONG_ARGUMENTS
|
||||||
|
SELECT 'a' LIKE 'a' ESCAPE TIMESTAMP'2001-01-01 00:00:00';
|
||||||
|
--error ER_WRONG_ARGUMENTS
|
||||||
|
SELECT 'a' LIKE 'a' ESCAPE TIME'00:00:00';
|
@ -226,6 +226,23 @@ my_bool check_datetime_range(const MYSQL_TIME *ltime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void get_microseconds(ulong *val, MYSQL_TIME_STATUS *status,
|
||||||
|
uint *number_of_fields,
|
||||||
|
const char **str, const char *end)
|
||||||
|
{
|
||||||
|
const char *start= *str;
|
||||||
|
uint tmp= 0; /* For the case '10:10:10.' */
|
||||||
|
if (get_digits(&tmp, number_of_fields, str, end, 6))
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
|
if ((status->precision= (*str - start)) < 6)
|
||||||
|
*val= tmp * log_10_int[6 - (*str - start)];
|
||||||
|
else
|
||||||
|
*val= tmp;
|
||||||
|
if (skip_digits(str, end))
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Convert a timestamp string to a MYSQL_TIME value.
|
Convert a timestamp string to a MYSQL_TIME value.
|
||||||
|
|
||||||
@ -240,9 +257,8 @@ my_bool check_datetime_range(const MYSQL_TIME *ltime)
|
|||||||
TIME_NO_ZERO_IN_DATE Don't allow partial dates
|
TIME_NO_ZERO_IN_DATE Don't allow partial dates
|
||||||
TIME_NO_ZERO_DATE Don't allow 0000-00-00 date
|
TIME_NO_ZERO_DATE Don't allow 0000-00-00 date
|
||||||
TIME_INVALID_DATES Allow 2000-02-31
|
TIME_INVALID_DATES Allow 2000-02-31
|
||||||
was_cut 0 Value OK
|
status Conversion status
|
||||||
1 If value was cut during conversion
|
|
||||||
2 check_date(date,flags) considers date invalid
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
At least the following formats are recogniced (based on number of digits)
|
At least the following formats are recogniced (based on number of digits)
|
||||||
@ -253,20 +269,29 @@ my_bool check_datetime_range(const MYSQL_TIME *ltime)
|
|||||||
|
|
||||||
The second part may have an optional .###### fraction part.
|
The second part may have an optional .###### fraction part.
|
||||||
|
|
||||||
RETURN VALUES
|
status->warnings is set to:
|
||||||
|
0 Value OK
|
||||||
|
MYSQL_TIME_WARN_TRUNCATED If value was cut during conversion
|
||||||
|
MYSQL_TIME_WARN_OUT_OF_RANGE check_date(date,flags) considers date invalid
|
||||||
|
|
||||||
|
l_time->time_type is set as follows:
|
||||||
MYSQL_TIMESTAMP_NONE String wasn't a timestamp, like
|
MYSQL_TIMESTAMP_NONE String wasn't a timestamp, like
|
||||||
[DD [HH:[MM:[SS]]]].fraction.
|
[DD [HH:[MM:[SS]]]].fraction.
|
||||||
|
l_time is not changed.
|
||||||
MYSQL_TIMESTAMP_DATE DATE string (YY MM and DD parts ok)
|
MYSQL_TIMESTAMP_DATE DATE string (YY MM and DD parts ok)
|
||||||
MYSQL_TIMESTAMP_DATETIME Full timestamp
|
MYSQL_TIMESTAMP_DATETIME Full timestamp
|
||||||
MYSQL_TIMESTAMP_ERROR Timestamp with wrong values.
|
MYSQL_TIMESTAMP_ERROR Timestamp with wrong values.
|
||||||
All elements in l_time is set to 0
|
All elements in l_time is set to 0
|
||||||
|
RETURN VALUES
|
||||||
|
0 - Ok
|
||||||
|
1 - Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_DATE_PARTS 8
|
#define MAX_DATE_PARTS 8
|
||||||
|
|
||||||
enum enum_mysql_timestamp_type
|
my_bool
|
||||||
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
||||||
ulonglong flags, int *was_cut)
|
ulonglong flags, MYSQL_TIME_STATUS *status)
|
||||||
{
|
{
|
||||||
const char *end=str+length, *pos;
|
const char *end=str+length, *pos;
|
||||||
uint number_of_fields= 0, digits, year_length, not_zero_date;
|
uint number_of_fields= 0, digits, year_length, not_zero_date;
|
||||||
@ -275,19 +300,20 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
|
|
||||||
if (flags & TIME_TIME_ONLY)
|
if (flags & TIME_TIME_ONLY)
|
||||||
{
|
{
|
||||||
enum enum_mysql_timestamp_type ret;
|
my_bool ret= str_to_time(str, length, l_time, flags, status);
|
||||||
ret= str_to_time(str, length, l_time, flags, was_cut);
|
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
*was_cut= 0;
|
|
||||||
|
my_time_status_init(status);
|
||||||
|
|
||||||
/* Skip space at start */
|
/* Skip space at start */
|
||||||
for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++)
|
for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++)
|
||||||
;
|
;
|
||||||
if (str == end || ! my_isdigit(&my_charset_latin1, *str))
|
if (str == end || ! my_isdigit(&my_charset_latin1, *str))
|
||||||
{
|
{
|
||||||
*was_cut= 1;
|
status->warnings= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
|
l_time->time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -316,55 +342,49 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
(only numbers like [YY]YYMMDD[T][hhmmss[.uuuuuu]])
|
(only numbers like [YY]YYMMDD[T][hhmmss[.uuuuuu]])
|
||||||
*/
|
*/
|
||||||
year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2;
|
year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2;
|
||||||
*was_cut= get_digits(&l_time->year, &number_of_fields, &str, end, year_length)
|
if (get_digits(&l_time->year, &number_of_fields, &str, end, year_length)
|
||||||
|| get_digits(&l_time->month, &number_of_fields, &str, end, 2)
|
|| get_digits(&l_time->month, &number_of_fields, &str, end, 2)
|
||||||
|| get_digits(&l_time->day, &number_of_fields, &str, end, 2)
|
|| get_digits(&l_time->day, &number_of_fields, &str, end, 2)
|
||||||
|| get_maybe_T(&str, end)
|
|| get_maybe_T(&str, end)
|
||||||
|| get_digits(&l_time->hour, &number_of_fields, &str, end, 2)
|
|| get_digits(&l_time->hour, &number_of_fields, &str, end, 2)
|
||||||
|| get_digits(&l_time->minute, &number_of_fields, &str, end, 2)
|
|| get_digits(&l_time->minute, &number_of_fields, &str, end, 2)
|
||||||
|| get_digits(&l_time->second, &number_of_fields, &str, end, 2);
|
|| get_digits(&l_time->second, &number_of_fields, &str, end, 2))
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *start= str;
|
const char *start= str;
|
||||||
*was_cut = get_number(&l_time->year, &number_of_fields, &str, end);
|
if (get_number(&l_time->year, &number_of_fields, &str, end))
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
year_length= str - start;
|
year_length= str - start;
|
||||||
|
|
||||||
if (!*was_cut)
|
if (!status->warnings &&
|
||||||
*was_cut= get_punct(&str, end)
|
(get_punct(&str, end)
|
||||||
|| get_number(&l_time->month, &number_of_fields, &str, end)
|
|| get_number(&l_time->month, &number_of_fields, &str, end)
|
||||||
|| get_punct(&str, end)
|
|| get_punct(&str, end)
|
||||||
|| get_number(&l_time->day, &number_of_fields, &str, end)
|
|| get_number(&l_time->day, &number_of_fields, &str, end)
|
||||||
|| get_date_time_separator(&number_of_fields, flags, &str, end)
|
|| get_date_time_separator(&number_of_fields, flags, &str, end)
|
||||||
|| get_number(&l_time->hour, &number_of_fields, &str, end)
|
|| get_number(&l_time->hour, &number_of_fields, &str, end)
|
||||||
|| get_punct(&str, end)
|
|| get_punct(&str, end)
|
||||||
|| get_number(&l_time->minute, &number_of_fields, &str, end)
|
|| get_number(&l_time->minute, &number_of_fields, &str, end)
|
||||||
|| get_punct(&str, end)
|
|| get_punct(&str, end)
|
||||||
|| get_number(&l_time->second, &number_of_fields, &str, end);
|
|| get_number(&l_time->second, &number_of_fields, &str, end)))
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (number_of_fields < 3)
|
|
||||||
*was_cut= 1;
|
|
||||||
|
|
||||||
/* we're ok if date part is correct. even if the rest is truncated */
|
/* we're ok if date part is correct. even if the rest is truncated */
|
||||||
if (*was_cut && number_of_fields < 3)
|
if (number_of_fields < 3)
|
||||||
DBUG_RETURN(MYSQL_TIMESTAMP_NONE);
|
|
||||||
|
|
||||||
if (!*was_cut && str < end && *str == '.')
|
|
||||||
{
|
{
|
||||||
uint second_part;
|
l_time->time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
const char *start= ++str;
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
*was_cut= get_digits(&second_part, &number_of_fields, &str, end, 6);
|
DBUG_RETURN(TRUE);
|
||||||
if (number_of_fields == 7)
|
}
|
||||||
{
|
|
||||||
if (str - start < 6)
|
if (!status->warnings && str < end && *str == '.')
|
||||||
second_part*= log_10_int[6 - (str - start)];
|
{
|
||||||
l_time->second_part= second_part;
|
str++;
|
||||||
}
|
get_microseconds(&l_time->second_part, status,
|
||||||
else
|
&number_of_fields, &str, end);
|
||||||
l_time->second_part= 0;
|
|
||||||
if (skip_digits(&str, end))
|
|
||||||
*was_cut= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
not_zero_date = l_time->year || l_time->month || l_time->day ||
|
not_zero_date = l_time->year || l_time->month || l_time->day ||
|
||||||
@ -377,11 +397,11 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
if (l_time->year > 9999 || l_time->month > 12 || l_time->day > 31 ||
|
if (l_time->year > 9999 || l_time->month > 12 || l_time->day > 31 ||
|
||||||
l_time->hour > 23 || l_time->minute > 59 || l_time->second > 59)
|
l_time->hour > 23 || l_time->minute > 59 || l_time->second > 59)
|
||||||
{
|
{
|
||||||
*was_cut= 1;
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_date(l_time, not_zero_date, flags, was_cut))
|
if (check_date(l_time, not_zero_date, flags, &status->warnings))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
l_time->time_type= (number_of_fields <= 3 ?
|
l_time->time_type= (number_of_fields <= 3 ?
|
||||||
@ -391,16 +411,17 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
{
|
{
|
||||||
if (!my_isspace(&my_charset_latin1,*str))
|
if (!my_isspace(&my_charset_latin1,*str))
|
||||||
{
|
{
|
||||||
*was_cut= 1;
|
status->warnings= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(l_time->time_type);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
bzero((char*) l_time, sizeof(*l_time));
|
bzero((char*) l_time, sizeof(*l_time));
|
||||||
DBUG_RETURN(MYSQL_TIMESTAMP_ERROR);
|
l_time->time_type= MYSQL_TIMESTAMP_ERROR;
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -415,23 +436,26 @@ 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
|
||||||
warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string
|
status Conversion status
|
||||||
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
|
||||||
work with times where the time arguments are in the above order.
|
work with times where the time arguments are in the above order.
|
||||||
|
|
||||||
|
status->warnings is set as follows:
|
||||||
|
MYSQL_TIME_WARN_TRUNCATED if the input string was cut during conversion,
|
||||||
|
and/or
|
||||||
|
MYSQL_TIME_WARN_OUT_OF_RANGE flag is set if the value is out of range.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
MYSQL_TIMESTAMP_TIME
|
FALSE on success
|
||||||
MYSQL_TIMESTAMP_ERROR
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum enum_mysql_timestamp_type
|
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
||||||
str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
ulonglong fuzzydate, MYSQL_TIME_STATUS *status)
|
||||||
ulonglong fuzzydate, int *warning)
|
|
||||||
{
|
{
|
||||||
ulong date[5];
|
ulong date[5];
|
||||||
ulonglong value;
|
ulonglong value;
|
||||||
@ -439,7 +463,7 @@ str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
my_bool found_days,found_hours, neg= 0;
|
my_bool found_days,found_hours, neg= 0;
|
||||||
uint UNINIT_VAR(state);
|
uint UNINIT_VAR(state);
|
||||||
|
|
||||||
*warning= 0;
|
my_time_status_init(status);
|
||||||
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 == '-')
|
||||||
@ -449,22 +473,20 @@ str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
if (str == end)
|
if (str == end)
|
||||||
return MYSQL_TIMESTAMP_ERROR;
|
{
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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;
|
(void) str_to_datetime(str, length, l_time,
|
||||||
enum enum_mysql_timestamp_type
|
|
||||||
res= str_to_datetime(str, length, l_time,
|
|
||||||
(fuzzydate & ~TIME_TIME_ONLY) | TIME_DATETIME_ONLY,
|
(fuzzydate & ~TIME_TIME_ONLY) | TIME_DATETIME_ONLY,
|
||||||
&was_cut);
|
status);
|
||||||
if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR)
|
if (l_time->time_type >= MYSQL_TIMESTAMP_ERROR)
|
||||||
{
|
return l_time->time_type == MYSQL_TIMESTAMP_ERROR;
|
||||||
if (was_cut)
|
my_time_status_init(status);
|
||||||
*warning|= MYSQL_TIME_WARN_TRUNCATED;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l_time->neg= neg;
|
l_time->neg= neg;
|
||||||
@ -532,24 +554,15 @@ str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
|
|||||||
|
|
||||||
fractional:
|
fractional:
|
||||||
/* Get fractional second part */
|
/* Get fractional second part */
|
||||||
if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1]))
|
if (!status->warnings && str < end && *str == '.')
|
||||||
{
|
{
|
||||||
int field_length= 5;
|
uint number_of_fields= 0;
|
||||||
str++; value=(uint) (uchar) (*str - '0');
|
str++;
|
||||||
while (++str != end && my_isdigit(&my_charset_latin1, *str))
|
get_microseconds(&date[4], status, &number_of_fields, &str, end);
|
||||||
{
|
|
||||||
if (field_length-- > 0)
|
|
||||||
value= value*10 + (uint) (uchar) (*str - '0');
|
|
||||||
}
|
|
||||||
if (field_length > 0)
|
|
||||||
value*= (long) log_10_int[field_length];
|
|
||||||
else if (field_length < 0)
|
|
||||||
*warning|= MYSQL_TIME_WARN_TRUNCATED;
|
|
||||||
date[4]= (ulong) value;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
date[4]=0;
|
date[4]= 0;
|
||||||
|
|
||||||
/* Check for exponent part: E<gigit> | E<sign><digit> */
|
/* Check for exponent part: E<gigit> | E<sign><digit> */
|
||||||
/* (may occur as result of %g formatting of time value) */
|
/* (may occur as result of %g formatting of time value) */
|
||||||
if ((end - str) > 1 &&
|
if ((end - str) > 1 &&
|
||||||
@ -558,7 +571,10 @@ 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]))))
|
||||||
return MYSQL_TIMESTAMP_ERROR;
|
{
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (internal_format_positions[7] != 255)
|
if (internal_format_positions[7] != 255)
|
||||||
{
|
{
|
||||||
@ -581,8 +597,11 @@ fractional:
|
|||||||
if (date[0] > UINT_MAX || date[1] > UINT_MAX ||
|
if (date[0] > UINT_MAX || date[1] > UINT_MAX ||
|
||||||
date[2] > UINT_MAX || date[3] > UINT_MAX ||
|
date[2] > UINT_MAX || date[3] > UINT_MAX ||
|
||||||
date[4] > UINT_MAX)
|
date[4] > UINT_MAX)
|
||||||
return MYSQL_TIMESTAMP_ERROR;
|
{
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
@ -593,9 +612,9 @@ fractional:
|
|||||||
l_time->time_type= MYSQL_TIMESTAMP_TIME;
|
l_time->time_type= MYSQL_TIMESTAMP_TIME;
|
||||||
|
|
||||||
/* Check if the value is valid and fits into MYSQL_TIME range */
|
/* Check if the value is valid and fits into MYSQL_TIME range */
|
||||||
if (check_time_range(l_time, 6, warning))
|
if (check_time_range(l_time, 6, &status->warnings))
|
||||||
return MYSQL_TIMESTAMP_ERROR;
|
return TRUE;
|
||||||
|
|
||||||
/* Check if there is garbage at end of the MYSQL_TIME specification */
|
/* Check if there is garbage at end of the MYSQL_TIME specification */
|
||||||
if (str != end)
|
if (str != end)
|
||||||
{
|
{
|
||||||
@ -603,12 +622,17 @@ fractional:
|
|||||||
{
|
{
|
||||||
if (!my_isspace(&my_charset_latin1,*str))
|
if (!my_isspace(&my_charset_latin1,*str))
|
||||||
{
|
{
|
||||||
*warning|= MYSQL_TIME_WARN_TRUNCATED;
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (++str != end);
|
} while (++str != end);
|
||||||
}
|
}
|
||||||
return MYSQL_TIMESTAMP_TIME;
|
return FALSE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
bzero((char*) l_time, sizeof(*l_time));
|
||||||
|
l_time->time_type= MYSQL_TIMESTAMP_ERROR;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -638,7 +662,10 @@ int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning)
|
|||||||
999000, 999900, 999990, 999999};
|
999000, 999900, 999990, 999999};
|
||||||
|
|
||||||
if (my_time->minute >= 60 || my_time->second >= 60)
|
if (my_time->minute >= 60 || my_time->second >= 60)
|
||||||
|
{
|
||||||
|
*warning|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
hour= my_time->hour + (24*my_time->day);
|
hour= my_time->hour + (24*my_time->day);
|
||||||
|
|
||||||
@ -1406,7 +1433,7 @@ double TIME_to_double(const MYSQL_TIME *my_time)
|
|||||||
return my_time->neg ? -d : d;
|
return my_time->neg ? -d : d;
|
||||||
}
|
}
|
||||||
|
|
||||||
longlong pack_time(MYSQL_TIME *my_time)
|
longlong pack_time(const MYSQL_TIME *my_time)
|
||||||
{
|
{
|
||||||
return ((((((my_time->year * 13ULL +
|
return ((((((my_time->year * 13ULL +
|
||||||
my_time->month) * 32ULL +
|
my_time->month) * 32ULL +
|
||||||
|
43
sql/field.cc
43
sql/field.cc
@ -1900,7 +1900,7 @@ bool Field::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
|
|||||||
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
||||||
if (!(res=val_str(&tmp)) ||
|
if (!(res=val_str(&tmp)) ||
|
||||||
str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
|
str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
|
||||||
ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
|
ltime, fuzzydate))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -4647,18 +4647,18 @@ int Field_timestamp::store_time_dec(MYSQL_TIME *ltime, uint dec)
|
|||||||
int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
|
int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
MYSQL_TIME l_time;
|
MYSQL_TIME l_time;
|
||||||
int error;
|
MYSQL_TIME_STATUS status;
|
||||||
int have_smth_to_conv;
|
bool have_smth_to_conv;
|
||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
|
|
||||||
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
|
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
|
||||||
have_smth_to_conv= (str_to_datetime(cs, from, len, &l_time,
|
have_smth_to_conv= !str_to_datetime(cs, from, len, &l_time,
|
||||||
(thd->variables.sql_mode &
|
(thd->variables.sql_mode &
|
||||||
MODE_NO_ZERO_DATE) |
|
MODE_NO_ZERO_DATE) |
|
||||||
MODE_NO_ZERO_IN_DATE, &error) >
|
MODE_NO_ZERO_IN_DATE, &status);
|
||||||
MYSQL_TIMESTAMP_ERROR);
|
return store_TIME_with_warning(thd, &l_time, &str,
|
||||||
return store_TIME_with_warning(thd, &l_time, &str, error, have_smth_to_conv);
|
status.warnings, have_smth_to_conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5154,18 +5154,16 @@ int Field_temporal_with_date::store_TIME_with_warning(MYSQL_TIME *ltime,
|
|||||||
int Field_temporal_with_date::store(const char *from, uint len, CHARSET_INFO *cs)
|
int Field_temporal_with_date::store(const char *from, uint len, CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
int error;
|
MYSQL_TIME_STATUS status;
|
||||||
enum enum_mysql_timestamp_type func_res;
|
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
|
bool func_res= !str_to_datetime(cs, from, len, <ime,
|
||||||
func_res= str_to_datetime(cs, from, len, <ime,
|
(TIME_FUZZY_DATE |
|
||||||
(TIME_FUZZY_DATE |
|
(thd->variables.sql_mode &
|
||||||
(thd->variables.sql_mode &
|
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
|
||||||
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
|
MODE_INVALID_DATES))),
|
||||||
MODE_INVALID_DATES))),
|
&status);
|
||||||
&error);
|
return store_TIME_with_warning(<ime, &str, status.warnings, func_res);
|
||||||
return store_TIME_with_warning(<ime, &str, error, func_res > MYSQL_TIMESTAMP_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5280,16 +5278,17 @@ void Field_time::store_TIME(MYSQL_TIME *ltime)
|
|||||||
int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
|
int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
|
MYSQL_TIME_STATUS status;
|
||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
int was_cut;
|
bool have_smth_to_conv=
|
||||||
int have_smth_to_conv=
|
!str_to_time(cs, from, len, <ime,
|
||||||
str_to_time(cs, from, len, <ime,
|
|
||||||
get_thd()->variables.sql_mode &
|
get_thd()->variables.sql_mode &
|
||||||
(MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE |
|
(MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE |
|
||||||
MODE_INVALID_DATES),
|
MODE_INVALID_DATES),
|
||||||
&was_cut) > MYSQL_TIMESTAMP_ERROR;
|
&status);
|
||||||
|
|
||||||
return store_TIME_with_warning(<ime, &str, was_cut, have_smth_to_conv);
|
return store_TIME_with_warning(<ime, &str,
|
||||||
|
status.warnings, have_smth_to_conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
93
sql/item.cc
93
sql/item.cc
@ -377,6 +377,27 @@ my_decimal *Item::val_decimal_from_time(my_decimal *decimal_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
longlong Item::val_int_from_date()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||||
|
return 0;
|
||||||
|
longlong v= TIME_to_ulonglong(<ime);
|
||||||
|
return ltime.neg ? -v : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double Item::val_real_from_date()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
if (get_date(<ime, TIME_FUZZY_DATE))
|
||||||
|
return 0;
|
||||||
|
return TIME_to_double(<ime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double Item::val_real_from_decimal()
|
double Item::val_real_from_decimal()
|
||||||
{
|
{
|
||||||
/* Note that fix_fields may not be called for Item_avg_field items */
|
/* Note that fix_fields may not be called for Item_avg_field items */
|
||||||
@ -1272,7 +1293,7 @@ bool Item::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
|
|||||||
String tmp(buff,sizeof(buff), &my_charset_bin),*res;
|
String tmp(buff,sizeof(buff), &my_charset_bin),*res;
|
||||||
if (!(res=val_str(&tmp)) ||
|
if (!(res=val_str(&tmp)) ||
|
||||||
str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
|
str_to_datetime_with_warn(res->charset(), res->ptr(), res->length(),
|
||||||
ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR)
|
ltime, fuzzydate))
|
||||||
goto err;
|
goto err;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6283,6 +6304,76 @@ Item_bin_string::Item_bin_string(const char *str, uint str_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_temporal_literal::eq(const Item *item, bool binary_cmp) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
item->basic_const_item() && type() == item->type() &&
|
||||||
|
field_type() == ((Item_temporal_literal *) item)->field_type() &&
|
||||||
|
!my_time_compare(&cached_time,
|
||||||
|
&((Item_temporal_literal *) item)->cached_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_date_literal::print(String *str, enum_query_type query_type)
|
||||||
|
{
|
||||||
|
str->append("DATE'");
|
||||||
|
char buf[MAX_DATE_STRING_REP_LENGTH];
|
||||||
|
my_date_to_str(&cached_time, buf);
|
||||||
|
str->append(buf);
|
||||||
|
str->append('\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_date_literal::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed);
|
||||||
|
*ltime= cached_time;
|
||||||
|
return (null_value= check_date_with_warn(ltime, fuzzy_date,
|
||||||
|
MYSQL_TIMESTAMP_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_datetime_literal::print(String *str, enum_query_type query_type)
|
||||||
|
{
|
||||||
|
str->append("TIMESTAMP'");
|
||||||
|
char buf[MAX_DATE_STRING_REP_LENGTH];
|
||||||
|
my_datetime_to_str(&cached_time, buf, decimals);
|
||||||
|
str->append(buf);
|
||||||
|
str->append('\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_datetime_literal::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed);
|
||||||
|
*ltime= cached_time;
|
||||||
|
return (null_value= check_date_with_warn(ltime, fuzzy_date,
|
||||||
|
MYSQL_TIMESTAMP_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_time_literal::print(String *str, enum_query_type query_type)
|
||||||
|
{
|
||||||
|
str->append("TIME'");
|
||||||
|
char buf[MAX_DATE_STRING_REP_LENGTH];
|
||||||
|
my_time_to_str(&cached_time, buf, decimals);
|
||||||
|
str->append(buf);
|
||||||
|
str->append('\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_time_literal::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed);
|
||||||
|
*ltime= cached_time;
|
||||||
|
if (fuzzy_date & TIME_TIME_ONLY)
|
||||||
|
return (null_value= false);
|
||||||
|
return (null_value= check_date_with_warn(ltime, fuzzy_date,
|
||||||
|
MYSQL_TIMESTAMP_ERROR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Pack data in buffer for sending.
|
Pack data in buffer for sending.
|
||||||
*/
|
*/
|
||||||
|
113
sql/item.h
113
sql/item.h
@ -599,7 +599,8 @@ public:
|
|||||||
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
|
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
|
||||||
PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
|
PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
|
||||||
XPATH_NODESET, XPATH_NODESET_CMP,
|
XPATH_NODESET, XPATH_NODESET_CMP,
|
||||||
VIEW_FIXER_ITEM, EXPR_CACHE_ITEM};
|
VIEW_FIXER_ITEM, EXPR_CACHE_ITEM,
|
||||||
|
DATE_ITEM};
|
||||||
|
|
||||||
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
|
||||||
|
|
||||||
@ -956,7 +957,9 @@ public:
|
|||||||
my_decimal *val_decimal_from_date(my_decimal *decimal_value);
|
my_decimal *val_decimal_from_date(my_decimal *decimal_value);
|
||||||
my_decimal *val_decimal_from_time(my_decimal *decimal_value);
|
my_decimal *val_decimal_from_time(my_decimal *decimal_value);
|
||||||
longlong val_int_from_decimal();
|
longlong val_int_from_decimal();
|
||||||
|
longlong val_int_from_date();
|
||||||
double val_real_from_decimal();
|
double val_real_from_decimal();
|
||||||
|
double val_real_from_date();
|
||||||
|
|
||||||
int save_time_in_field(Field *field);
|
int save_time_in_field(Field *field);
|
||||||
int save_date_in_field(Field *field);
|
int save_date_in_field(Field *field);
|
||||||
@ -1113,8 +1116,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual CHARSET_INFO *charset_for_protocol(void) const
|
virtual CHARSET_INFO *charset_for_protocol(void) const
|
||||||
{
|
{
|
||||||
return result_type() == STRING_RESULT ? collation.collation :
|
return cmp_type() == STRING_RESULT ? collation.collation :
|
||||||
&my_charset_bin;
|
&my_charset_bin;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
|
virtual bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
|
||||||
@ -2877,6 +2880,110 @@ public:
|
|||||||
Item_bin_string(const char *str,uint str_length);
|
Item_bin_string(const char *str,uint str_length);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Item_temporal_literal :public Item_basic_constant
|
||||||
|
{
|
||||||
|
//sql_mode= current_thd->variables.sql_mode &
|
||||||
|
// (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
|
||||||
|
protected:
|
||||||
|
MYSQL_TIME cached_time;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Constructor for Item_date_literal.
|
||||||
|
@param ltime DATE value.
|
||||||
|
*/
|
||||||
|
Item_temporal_literal(MYSQL_TIME *ltime) :Item_basic_constant()
|
||||||
|
{
|
||||||
|
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
|
||||||
|
decimals= 0;
|
||||||
|
cached_time= *ltime;
|
||||||
|
}
|
||||||
|
Item_temporal_literal(MYSQL_TIME *ltime, uint dec_arg) :Item_basic_constant()
|
||||||
|
{
|
||||||
|
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
|
||||||
|
decimals= dec_arg;
|
||||||
|
cached_time= *ltime;
|
||||||
|
}
|
||||||
|
bool basic_const_item() const { return true; }
|
||||||
|
bool const_item() const { return true; }
|
||||||
|
enum Type type() const { return DATE_ITEM; }
|
||||||
|
bool eq(const Item *item, bool binary_cmp) const;
|
||||||
|
enum Item_result result_type () const { return STRING_RESULT; }
|
||||||
|
Item_result cmp_type() const { return TIME_RESULT; }
|
||||||
|
|
||||||
|
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
|
||||||
|
bool check_vcol_func_processor(uchar *arg) { return FALSE;}
|
||||||
|
|
||||||
|
String *val_str(String *str)
|
||||||
|
{ return val_string_from_date(str); }
|
||||||
|
longlong val_int()
|
||||||
|
{ return val_int_from_date(); }
|
||||||
|
double val_real()
|
||||||
|
{ return val_real_from_date(); }
|
||||||
|
my_decimal *val_decimal(my_decimal *decimal_value)
|
||||||
|
{ return val_decimal_from_date(decimal_value); }
|
||||||
|
Field *tmp_table_field(TABLE *table)
|
||||||
|
{ return tmp_table_field_from_field_type(table, 0); }
|
||||||
|
int save_in_field(Field *field, bool no_conversions)
|
||||||
|
{ return save_date_in_field(field); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
DATE'2010-01-01'
|
||||||
|
*/
|
||||||
|
class Item_date_literal: public Item_temporal_literal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item_date_literal(MYSQL_TIME *ltime)
|
||||||
|
:Item_temporal_literal(ltime)
|
||||||
|
{
|
||||||
|
max_length= MAX_DATE_WIDTH;
|
||||||
|
fixed= 1;
|
||||||
|
}
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||||
|
void print(String *str, enum_query_type query_type);
|
||||||
|
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
TIME'10:10:10'
|
||||||
|
*/
|
||||||
|
class Item_time_literal: public Item_temporal_literal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item_time_literal(MYSQL_TIME *ltime, uint dec_arg)
|
||||||
|
:Item_temporal_literal(ltime, dec_arg)
|
||||||
|
{
|
||||||
|
max_length= MIN_TIME_WIDTH + (decimals ? decimals + 1 : 0);
|
||||||
|
fixed= 1;
|
||||||
|
}
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
|
||||||
|
void print(String *str, enum_query_type query_type);
|
||||||
|
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
TIMESTAMP'2001-01-01 10:20:30'
|
||||||
|
*/
|
||||||
|
class Item_datetime_literal: public Item_temporal_literal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item_datetime_literal(MYSQL_TIME *ltime, uint dec_arg)
|
||||||
|
:Item_temporal_literal(ltime, dec_arg)
|
||||||
|
{
|
||||||
|
max_length= MAX_DATETIME_WIDTH + (decimals ? decimals + 1 : 0);
|
||||||
|
fixed= 1;
|
||||||
|
}
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||||
|
void print(String *str, enum_query_type query_type);
|
||||||
|
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Item_result_field :public Item /* Item with result field */
|
class Item_result_field :public Item /* Item with result field */
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -721,31 +721,31 @@ bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
|
|||||||
const char *warn_name, MYSQL_TIME *l_time)
|
const char *warn_name, MYSQL_TIME *l_time)
|
||||||
{
|
{
|
||||||
bool value;
|
bool value;
|
||||||
int error;
|
MYSQL_TIME_STATUS status;
|
||||||
enum_mysql_timestamp_type timestamp_type;
|
|
||||||
int flags= TIME_FUZZY_DATE | MODE_INVALID_DATES;
|
int flags= TIME_FUZZY_DATE | MODE_INVALID_DATES;
|
||||||
ErrConvString err(str);
|
ErrConvString err(str);
|
||||||
|
|
||||||
if (warn_type == MYSQL_TIMESTAMP_TIME)
|
DBUG_ASSERT(warn_type != MYSQL_TIMESTAMP_TIME);
|
||||||
flags|= TIME_TIME_ONLY;
|
|
||||||
|
|
||||||
timestamp_type=
|
if (!str_to_datetime(str->charset(), str->ptr(), str->length(),
|
||||||
str_to_datetime(str->charset(), str->ptr(), str->length(),
|
l_time, flags, &status))
|
||||||
l_time, flags, &error);
|
{
|
||||||
|
DBUG_ASSERT(l_time->time_type == MYSQL_TIMESTAMP_DATETIME ||
|
||||||
if (timestamp_type > MYSQL_TIMESTAMP_ERROR)
|
l_time->time_type == MYSQL_TIMESTAMP_DATE);
|
||||||
/*
|
/*
|
||||||
Do not return yet, we may still want to throw a "trailing garbage"
|
Do not return yet, we may still want to throw a "trailing garbage"
|
||||||
warning.
|
warning.
|
||||||
*/
|
*/
|
||||||
value= FALSE;
|
value= FALSE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(l_time->time_type != MYSQL_TIMESTAMP_TIME);
|
||||||
|
DBUG_ASSERT(status.warnings != 0); // Must be set by set_to_datetime()
|
||||||
value= TRUE;
|
value= TRUE;
|
||||||
error= 1; /* force warning */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error > 0)
|
if (status.warnings > 0)
|
||||||
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
&err, warn_type, warn_name);
|
&err, warn_type, warn_name);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "set_var.h"
|
#include "set_var.h"
|
||||||
#include "sp_head.h"
|
#include "sp_head.h"
|
||||||
#include "sp.h"
|
#include "sp.h"
|
||||||
|
#include "sql_time.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============================================================================
|
=============================================================================
|
||||||
@ -5821,6 +5822,70 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Builder for datetime literals:
|
||||||
|
TIME'00:00:00', DATE'2001-01-01', TIMESTAMP'2001-01-01 00:00:00'.
|
||||||
|
@param thd The current thread
|
||||||
|
@param str Character literal
|
||||||
|
@param length Length of str
|
||||||
|
@param type Type of literal (TIME, DATE or DATETIME)
|
||||||
|
@param send_error Whether to generate an error on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
Item *create_temporal_literal(THD *thd,
|
||||||
|
const char *str, uint length,
|
||||||
|
CHARSET_INFO *cs,
|
||||||
|
enum_field_types type,
|
||||||
|
bool send_error)
|
||||||
|
{
|
||||||
|
MYSQL_TIME_STATUS status;
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
Item *item= NULL;
|
||||||
|
ulonglong datetime_flags= thd->variables.sql_mode &
|
||||||
|
(MODE_NO_ZERO_IN_DATE |
|
||||||
|
MODE_NO_ZERO_DATE |
|
||||||
|
MODE_INVALID_DATES);
|
||||||
|
ulonglong flags= TIME_FUZZY_DATE | datetime_flags;
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_DATE:
|
||||||
|
case MYSQL_TYPE_NEWDATE:
|
||||||
|
if (!str_to_datetime(cs, str, length, <ime, flags, &status) &&
|
||||||
|
ltime.time_type == MYSQL_TIMESTAMP_DATE && !status.warnings)
|
||||||
|
item= new (thd->mem_root) Item_date_literal(<ime);
|
||||||
|
break;
|
||||||
|
case MYSQL_TYPE_DATETIME:
|
||||||
|
if (!str_to_datetime(cs, str, length, <ime, flags, &status) &&
|
||||||
|
ltime.time_type == MYSQL_TIMESTAMP_DATETIME && !status.warnings)
|
||||||
|
item= new (thd->mem_root) Item_datetime_literal(<ime,
|
||||||
|
status.precision);
|
||||||
|
break;
|
||||||
|
case MYSQL_TYPE_TIME:
|
||||||
|
if (!str_to_time(cs, str, length, <ime, 0, &status) &&
|
||||||
|
ltime.time_type == MYSQL_TIMESTAMP_TIME && !status.warnings)
|
||||||
|
item= new (thd->mem_root) Item_time_literal(<ime,
|
||||||
|
status.precision);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
return item;
|
||||||
|
|
||||||
|
if (send_error)
|
||||||
|
{
|
||||||
|
const char *typestr=
|
||||||
|
(type == MYSQL_TYPE_DATE) ? "DATE" :
|
||||||
|
(type == MYSQL_TYPE_TIME) ? "TIME" : "DATETIME";
|
||||||
|
ErrConvString err(str, length, thd->variables.character_set_client);
|
||||||
|
my_error(ER_WRONG_VALUE, MYF(0), typestr, err.ptr());
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static List<Item> *create_func_dyncol_prepare(THD *thd,
|
static List<Item> *create_func_dyncol_prepare(THD *thd,
|
||||||
DYNCALL_CREATE_DEF **dfs,
|
DYNCALL_CREATE_DEF **dfs,
|
||||||
List<DYNCALL_CREATE_DEF> &list)
|
List<DYNCALL_CREATE_DEF> &list)
|
||||||
|
@ -168,6 +168,11 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type,
|
|||||||
const char *len, const char *dec,
|
const char *len, const char *dec,
|
||||||
CHARSET_INFO *cs);
|
CHARSET_INFO *cs);
|
||||||
|
|
||||||
|
Item *create_temporal_literal(THD *thd,
|
||||||
|
const char *str, uint length,
|
||||||
|
CHARSET_INFO *cs,
|
||||||
|
enum_field_types type,
|
||||||
|
bool send_error);
|
||||||
|
|
||||||
int item_create_init();
|
int item_create_init();
|
||||||
void item_create_cleanup();
|
void item_create_cleanup();
|
||||||
|
@ -4725,7 +4725,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
|||||||
if (str_to_datetime_with_warn(&my_charset_numeric,
|
if (str_to_datetime_with_warn(&my_charset_numeric,
|
||||||
val.x.string.value.str,
|
val.x.string.value.str,
|
||||||
val.x.string.value.length,
|
val.x.string.value.length,
|
||||||
ltime, fuzzy_date) <= MYSQL_TIMESTAMP_ERROR)
|
ltime, fuzzy_date))
|
||||||
goto null;
|
goto null;
|
||||||
return 0;
|
return 0;
|
||||||
case DYN_COL_DATETIME:
|
case DYN_COL_DATETIME:
|
||||||
|
@ -2430,17 +2430,8 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
|
|||||||
|
|
||||||
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
|
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
|
||||||
ltime->time_type= MYSQL_TIMESTAMP_DATE;
|
ltime->time_type= MYSQL_TIMESTAMP_DATE;
|
||||||
|
return (null_value= check_date_with_warn(ltime, fuzzy_date,
|
||||||
int unused;
|
MYSQL_TIMESTAMP_DATE));
|
||||||
if (check_date(ltime, ltime->year || ltime->month || ltime->day,
|
|
||||||
fuzzy_date, &unused))
|
|
||||||
{
|
|
||||||
ErrConvTime str(ltime);
|
|
||||||
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
||||||
&str, MYSQL_TIMESTAMP_DATE, 0);
|
|
||||||
return (null_value= 1);
|
|
||||||
}
|
|
||||||
return (null_value= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -489,7 +489,6 @@ public:
|
|||||||
Item_temporal_func(Item *a, Item *b) :Item_func(a,b) {}
|
Item_temporal_func(Item *a, Item *b) :Item_func(a,b) {}
|
||||||
Item_temporal_func(Item *a, Item *b, Item *c) :Item_func(a,b,c) {}
|
Item_temporal_func(Item *a, Item *b, Item *c) :Item_func(a,b,c) {}
|
||||||
enum Item_result result_type () const { return STRING_RESULT; }
|
enum Item_result result_type () const { return STRING_RESULT; }
|
||||||
CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
|
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||||
Item_result cmp_type() const { return TIME_RESULT; }
|
Item_result cmp_type() const { return TIME_RESULT; }
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
|
@ -14696,6 +14696,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
case Item::REAL_ITEM:
|
case Item::REAL_ITEM:
|
||||||
case Item::DECIMAL_ITEM:
|
case Item::DECIMAL_ITEM:
|
||||||
case Item::STRING_ITEM:
|
case Item::STRING_ITEM:
|
||||||
|
case Item::DATE_ITEM:
|
||||||
case Item::REF_ITEM:
|
case Item::REF_ITEM:
|
||||||
case Item::NULL_ITEM:
|
case Item::NULL_ITEM:
|
||||||
case Item::VARBIN_ITEM:
|
case Item::VARBIN_ITEM:
|
||||||
|
@ -214,6 +214,22 @@ ulong convert_month_to_period(ulong month)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
check_date_with_warn(const MYSQL_TIME *ltime, ulonglong fuzzy_date,
|
||||||
|
timestamp_type ts_type)
|
||||||
|
{
|
||||||
|
int unused;
|
||||||
|
if (check_date(ltime, fuzzy_date, &unused))
|
||||||
|
{
|
||||||
|
ErrConvTime str(ltime);
|
||||||
|
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
|
&str, ts_type, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Convert a string to 8-bit representation,
|
Convert a string to 8-bit representation,
|
||||||
for use in str_to_time/str_to_date/str_to_date.
|
for use in str_to_time/str_to_date/str_to_date.
|
||||||
@ -249,9 +265,9 @@ to_ascii(CHARSET_INFO *cs,
|
|||||||
|
|
||||||
|
|
||||||
/* Character set-aware version of str_to_time() */
|
/* Character set-aware version of str_to_time() */
|
||||||
timestamp_type
|
bool
|
||||||
str_to_time(CHARSET_INFO *cs, const char *str,uint length,
|
str_to_time(CHARSET_INFO *cs, const char *str,uint length,
|
||||||
MYSQL_TIME *l_time, ulonglong fuzzydate, int *warning)
|
MYSQL_TIME *l_time, ulonglong fuzzydate, MYSQL_TIME_STATUS *status)
|
||||||
{
|
{
|
||||||
char cnv[32];
|
char cnv[32];
|
||||||
if ((cs->state & MY_CS_NONASCII) != 0)
|
if ((cs->state & MY_CS_NONASCII) != 0)
|
||||||
@ -259,14 +275,14 @@ str_to_time(CHARSET_INFO *cs, const char *str,uint length,
|
|||||||
length= to_ascii(cs, str, length, cnv, sizeof(cnv));
|
length= to_ascii(cs, str, length, cnv, sizeof(cnv));
|
||||||
str= cnv;
|
str= cnv;
|
||||||
}
|
}
|
||||||
return str_to_time(str, length, l_time, fuzzydate, warning);
|
return str_to_time(str, length, l_time, fuzzydate, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Character set-aware version of str_to_datetime() */
|
/* Character set-aware version of str_to_datetime() */
|
||||||
timestamp_type str_to_datetime(CHARSET_INFO *cs,
|
bool str_to_datetime(CHARSET_INFO *cs, const char *str, uint length,
|
||||||
const char *str, uint length,
|
MYSQL_TIME *l_time, ulonglong flags,
|
||||||
MYSQL_TIME *l_time, ulonglong flags, int *was_cut)
|
MYSQL_TIME_STATUS *status)
|
||||||
{
|
{
|
||||||
char cnv[32];
|
char cnv[32];
|
||||||
if ((cs->state & MY_CS_NONASCII) != 0)
|
if ((cs->state & MY_CS_NONASCII) != 0)
|
||||||
@ -274,7 +290,7 @@ timestamp_type str_to_datetime(CHARSET_INFO *cs,
|
|||||||
length= to_ascii(cs, str, length, cnv, sizeof(cnv));
|
length= to_ascii(cs, str, length, cnv, sizeof(cnv));
|
||||||
str= cnv;
|
str= cnv;
|
||||||
}
|
}
|
||||||
return str_to_datetime(str, length, l_time, flags, was_cut);
|
return str_to_datetime(str, length, l_time, flags, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -286,26 +302,24 @@ timestamp_type str_to_datetime(CHARSET_INFO *cs,
|
|||||||
See description of str_to_datetime() for more information.
|
See description of str_to_datetime() for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
timestamp_type
|
bool
|
||||||
str_to_datetime_with_warn(CHARSET_INFO *cs,
|
str_to_datetime_with_warn(CHARSET_INFO *cs,
|
||||||
const char *str, uint length, MYSQL_TIME *l_time,
|
const char *str, uint length, MYSQL_TIME *l_time,
|
||||||
ulonglong flags)
|
ulonglong flags)
|
||||||
{
|
{
|
||||||
int was_cut;
|
MYSQL_TIME_STATUS status;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
timestamp_type ts_type;
|
bool ret_val= str_to_datetime(cs, str, length, l_time,
|
||||||
|
|
||||||
ts_type= str_to_datetime(cs, str, length, l_time,
|
|
||||||
(flags | (sql_mode_for_dates(thd))),
|
(flags | (sql_mode_for_dates(thd))),
|
||||||
&was_cut);
|
&status);
|
||||||
if (was_cut || ts_type <= MYSQL_TIMESTAMP_ERROR)
|
if (ret_val || status.warnings)
|
||||||
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
str, length, flags & TIME_TIME_ONLY ?
|
str, length, flags & TIME_TIME_ONLY ?
|
||||||
MYSQL_TIMESTAMP_TIME : ts_type, NullS);
|
MYSQL_TIMESTAMP_TIME : l_time->time_type, NullS);
|
||||||
DBUG_EXECUTE_IF("str_to_datetime_warn",
|
DBUG_EXECUTE_IF("str_to_datetime_warn",
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||||
ER_YES, str););
|
ER_YES, str););
|
||||||
return ts_type;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1055,7 +1069,7 @@ calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign, longlong *s
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
|
int my_time_compare(const MYSQL_TIME *a, const MYSQL_TIME *b)
|
||||||
{
|
{
|
||||||
ulonglong a_t= pack_time(a);
|
ulonglong a_t= pack_time(a);
|
||||||
ulonglong b_t= pack_time(b);
|
ulonglong b_t= pack_time(b);
|
||||||
|
@ -35,11 +35,9 @@ ulong convert_period_to_month(ulong period);
|
|||||||
ulong convert_month_to_period(ulong month);
|
ulong convert_month_to_period(ulong month);
|
||||||
bool get_date_from_daynr(long daynr,uint *year, uint *month, uint *day);
|
bool get_date_from_daynr(long daynr,uint *year, uint *month, uint *day);
|
||||||
my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code);
|
my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, uint *error_code);
|
||||||
bool str_to_time_with_warn(CHARSET_INFO *cs, const char *str, uint length,
|
bool str_to_datetime_with_warn(CHARSET_INFO *cs, const char *str,
|
||||||
MYSQL_TIME *l_time, ulonglong fuzzydate);
|
uint length, MYSQL_TIME *l_time,
|
||||||
timestamp_type str_to_datetime_with_warn(CHARSET_INFO *cs, const char *str,
|
ulonglong flags);
|
||||||
uint length, MYSQL_TIME *l_time,
|
|
||||||
ulonglong flags);
|
|
||||||
bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime,
|
bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime,
|
||||||
ulonglong fuzzydate,
|
ulonglong fuzzydate,
|
||||||
const char *name);
|
const char *name);
|
||||||
@ -76,7 +74,7 @@ bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type,
|
|||||||
INTERVAL interval);
|
INTERVAL interval);
|
||||||
bool calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign,
|
bool calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign,
|
||||||
longlong *seconds_out, long *microseconds_out);
|
longlong *seconds_out, long *microseconds_out);
|
||||||
int my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b);
|
int my_time_compare(const MYSQL_TIME *a, const MYSQL_TIME *b);
|
||||||
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
|
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from);
|
||||||
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds);
|
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds);
|
||||||
uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year);
|
uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year);
|
||||||
@ -86,12 +84,14 @@ bool parse_date_time_format(timestamp_type format_type,
|
|||||||
const char *format, uint format_length,
|
const char *format, uint format_length,
|
||||||
DATE_TIME_FORMAT *date_time_format);
|
DATE_TIME_FORMAT *date_time_format);
|
||||||
/* Character set-aware version of str_to_time() */
|
/* Character set-aware version of str_to_time() */
|
||||||
timestamp_type str_to_time(CHARSET_INFO *cs, const char *str,uint length,
|
bool str_to_time(CHARSET_INFO *cs, const char *str,uint length,
|
||||||
MYSQL_TIME *l_time, ulonglong fuzzydate, int *warning);
|
MYSQL_TIME *l_time, ulonglong fuzzydate,
|
||||||
|
MYSQL_TIME_STATUS *status);
|
||||||
/* Character set-aware version of str_to_datetime() */
|
/* Character set-aware version of str_to_datetime() */
|
||||||
timestamp_type str_to_datetime(CHARSET_INFO *cs,
|
bool str_to_datetime(CHARSET_INFO *cs,
|
||||||
const char *str, uint length,
|
const char *str, uint length,
|
||||||
MYSQL_TIME *l_time, ulonglong flags, int *was_cut);
|
MYSQL_TIME *l_time, ulonglong flags,
|
||||||
|
MYSQL_TIME_STATUS *status);
|
||||||
|
|
||||||
/* convenience wrapper */
|
/* convenience wrapper */
|
||||||
inline bool parse_date_time_format(timestamp_type format_type,
|
inline bool parse_date_time_format(timestamp_type format_type,
|
||||||
@ -110,4 +110,18 @@ extern DATE_TIME_FORMAT global_time_format;
|
|||||||
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
|
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
|
||||||
extern LEX_STRING interval_type_to_name[];
|
extern LEX_STRING interval_type_to_name[];
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
non_zero_date(const MYSQL_TIME *ltime)
|
||||||
|
{
|
||||||
|
return ltime->year || ltime->month || ltime->day;
|
||||||
|
}
|
||||||
|
static inline bool
|
||||||
|
check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut)
|
||||||
|
{
|
||||||
|
return check_date(ltime, non_zero_date(ltime), flags, was_cut);
|
||||||
|
}
|
||||||
|
bool check_date_with_warn(const MYSQL_TIME *ltime, ulonglong fuzzy_date,
|
||||||
|
timestamp_type ts_type);
|
||||||
|
|
||||||
#endif /* SQL_TIME_INCLUDED */
|
#endif /* SQL_TIME_INCLUDED */
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#define YYTHD ((THD *)yythd)
|
#define YYTHD ((THD *)yythd)
|
||||||
#define YYLIP (& YYTHD->m_parser_state->m_lip)
|
#define YYLIP (& YYTHD->m_parser_state->m_lip)
|
||||||
#define YYPS (& YYTHD->m_parser_state->m_yacc)
|
#define YYPS (& YYTHD->m_parser_state->m_yacc)
|
||||||
|
#define YYCSCL YYTHD->variables.character_set_client
|
||||||
|
|
||||||
#define MYSQL_YACC
|
#define MYSQL_YACC
|
||||||
#define YYINITDEPTH 100
|
#define YYINITDEPTH 100
|
||||||
@ -899,10 +900,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
|
|
||||||
%pure_parser /* We have threads */
|
%pure_parser /* We have threads */
|
||||||
/*
|
/*
|
||||||
Currently there are 170 shift/reduce conflicts.
|
Currently there are 167 shift/reduce conflicts.
|
||||||
We should not introduce new conflicts any more.
|
We should not introduce new conflicts any more.
|
||||||
*/
|
*/
|
||||||
%expect 170
|
%expect 167
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Comments for TOKENS.
|
Comments for TOKENS.
|
||||||
@ -1628,7 +1629,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
replace_lock_option opt_low_priority insert_lock_option load_data_lock
|
replace_lock_option opt_low_priority insert_lock_option load_data_lock
|
||||||
|
|
||||||
%type <item>
|
%type <item>
|
||||||
literal text_literal insert_ident order_ident
|
literal text_literal insert_ident order_ident temporal_literal
|
||||||
simple_ident expr opt_expr opt_else sum_expr in_sum_expr
|
simple_ident expr opt_expr opt_else sum_expr in_sum_expr
|
||||||
variable variable_aux bool_pri
|
variable variable_aux bool_pri
|
||||||
predicate bit_expr
|
predicate bit_expr
|
||||||
@ -8741,7 +8742,48 @@ simple_expr:
|
|||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| '{' ident expr '}'
|
| '{' ident expr '}'
|
||||||
{ $$= $3; }
|
{
|
||||||
|
Item_string *item;
|
||||||
|
$$= NULL;
|
||||||
|
/*
|
||||||
|
If "expr" is reasonably short pure ASCII string literal,
|
||||||
|
try to parse known ODBC style date, time or timestamp literals,
|
||||||
|
e.g:
|
||||||
|
SELECT {d'2001-01-01'};
|
||||||
|
SELECT {t'10:20:30'};
|
||||||
|
SELECT {ts'2001-01-01 10:20:30'};
|
||||||
|
*/
|
||||||
|
if ($3->type() == Item::STRING_ITEM &&
|
||||||
|
(item= (Item_string *) $3) &&
|
||||||
|
item->collation.repertoire == MY_REPERTOIRE_ASCII &&
|
||||||
|
item->str_value.length() < MAX_DATE_STRING_REP_LENGTH * 4)
|
||||||
|
{
|
||||||
|
enum_field_types type= MYSQL_TYPE_STRING;
|
||||||
|
LEX_STRING *ls= &$2;
|
||||||
|
if (ls->length == 1)
|
||||||
|
{
|
||||||
|
if (ls->str[0] == 'd') /* {d'2001-01-01'} */
|
||||||
|
type= MYSQL_TYPE_DATE;
|
||||||
|
else if (ls->str[0] == 't') /* {t'10:20:30'} */
|
||||||
|
type= MYSQL_TYPE_TIME;
|
||||||
|
}
|
||||||
|
else if (ls->length == 2) /* {ts'2001-01-01 10:20:30'} */
|
||||||
|
{
|
||||||
|
if (ls->str[0] == 't' && ls->str[1] == 's')
|
||||||
|
type= MYSQL_TYPE_DATETIME;
|
||||||
|
}
|
||||||
|
if (type != MYSQL_TYPE_STRING)
|
||||||
|
{
|
||||||
|
$$= create_temporal_literal(YYTHD,
|
||||||
|
item->str_value.ptr(),
|
||||||
|
item->str_value.length(),
|
||||||
|
item->str_value.charset(),
|
||||||
|
type, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($$ == NULL)
|
||||||
|
$$= $3;
|
||||||
|
}
|
||||||
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
|
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
|
||||||
{
|
{
|
||||||
$2->push_front($5);
|
$2->push_front($5);
|
||||||
@ -12730,6 +12772,7 @@ signed_literal:
|
|||||||
literal:
|
literal:
|
||||||
text_literal { $$ = $1; }
|
text_literal { $$ = $1; }
|
||||||
| NUM_literal { $$ = $1; }
|
| NUM_literal { $$ = $1; }
|
||||||
|
| temporal_literal { $$= $1; }
|
||||||
| NULL_SYM
|
| NULL_SYM
|
||||||
{
|
{
|
||||||
$$ = new (YYTHD->mem_root) Item_null();
|
$$ = new (YYTHD->mem_root) Item_null();
|
||||||
@ -12824,9 +12867,6 @@ literal:
|
|||||||
|
|
||||||
$$= item_str;
|
$$= item_str;
|
||||||
}
|
}
|
||||||
| DATE_SYM text_literal { $$ = $2; }
|
|
||||||
| TIME_SYM text_literal { $$ = $2; }
|
|
||||||
| TIMESTAMP text_literal { $$ = $2; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
NUM_literal:
|
NUM_literal:
|
||||||
@ -12875,6 +12915,31 @@ NUM_literal:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
temporal_literal:
|
||||||
|
DATE_SYM TEXT_STRING
|
||||||
|
{
|
||||||
|
if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
|
||||||
|
MYSQL_TYPE_DATE, true)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| TIME_SYM TEXT_STRING
|
||||||
|
{
|
||||||
|
if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
|
||||||
|
MYSQL_TYPE_TIME, true)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| TIMESTAMP TEXT_STRING
|
||||||
|
{
|
||||||
|
if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
|
||||||
|
MYSQL_TYPE_DATETIME, true)))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
** Creating different items.
|
** Creating different items.
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
@ -567,7 +567,7 @@ int spider_db_mysql_result::fetch_table_status(
|
|||||||
#else
|
#else
|
||||||
my_bool not_used_my_bool;
|
my_bool not_used_my_bool;
|
||||||
#endif
|
#endif
|
||||||
int not_used_int;
|
MYSQL_TIME_STATUS time_status;
|
||||||
long not_used_long;
|
long not_used_long;
|
||||||
DBUG_ENTER("spider_db_mysql_result::fetch_table_status");
|
DBUG_ENTER("spider_db_mysql_result::fetch_table_status");
|
||||||
DBUG_PRINT("info",("spider this=%p", this));
|
DBUG_PRINT("info",("spider this=%p", this));
|
||||||
@ -628,8 +628,9 @@ int spider_db_mysql_result::fetch_table_status(
|
|||||||
("spider auto_increment_value=%lld", auto_increment_value));
|
("spider auto_increment_value=%lld", auto_increment_value));
|
||||||
if (mysql_row[11])
|
if (mysql_row[11])
|
||||||
{
|
{
|
||||||
|
my_time_status_init(&time_status);
|
||||||
str_to_datetime(mysql_row[11], strlen(mysql_row[11]), &mysql_time, 0,
|
str_to_datetime(mysql_row[11], strlen(mysql_row[11]), &mysql_time, 0,
|
||||||
¬_used_int);
|
&time_status);
|
||||||
#ifdef MARIADB_BASE_VERSION
|
#ifdef MARIADB_BASE_VERSION
|
||||||
create_time = (time_t) my_system_gmt_sec(&mysql_time,
|
create_time = (time_t) my_system_gmt_sec(&mysql_time,
|
||||||
¬_used_long, ¬_used_uint);
|
¬_used_long, ¬_used_uint);
|
||||||
@ -650,8 +651,9 @@ int spider_db_mysql_result::fetch_table_status(
|
|||||||
#endif
|
#endif
|
||||||
if (mysql_row[12])
|
if (mysql_row[12])
|
||||||
{
|
{
|
||||||
|
my_time_status_init(&time_status);
|
||||||
str_to_datetime(mysql_row[12], strlen(mysql_row[12]), &mysql_time, 0,
|
str_to_datetime(mysql_row[12], strlen(mysql_row[12]), &mysql_time, 0,
|
||||||
¬_used_int);
|
&time_status);
|
||||||
#ifdef MARIADB_BASE_VERSION
|
#ifdef MARIADB_BASE_VERSION
|
||||||
update_time = (time_t) my_system_gmt_sec(&mysql_time,
|
update_time = (time_t) my_system_gmt_sec(&mysql_time,
|
||||||
¬_used_long, ¬_used_uint);
|
¬_used_long, ¬_used_uint);
|
||||||
@ -672,8 +674,9 @@ int spider_db_mysql_result::fetch_table_status(
|
|||||||
#endif
|
#endif
|
||||||
if (mysql_row[13])
|
if (mysql_row[13])
|
||||||
{
|
{
|
||||||
|
my_time_status_init(&time_status);
|
||||||
str_to_datetime(mysql_row[13], strlen(mysql_row[13]), &mysql_time, 0,
|
str_to_datetime(mysql_row[13], strlen(mysql_row[13]), &mysql_time, 0,
|
||||||
¬_used_int);
|
&time_status);
|
||||||
#ifdef MARIADB_BASE_VERSION
|
#ifdef MARIADB_BASE_VERSION
|
||||||
check_time = (time_t) my_system_gmt_sec(&mysql_time,
|
check_time = (time_t) my_system_gmt_sec(&mysql_time,
|
||||||
¬_used_long, ¬_used_uint);
|
¬_used_long, ¬_used_uint);
|
||||||
@ -737,8 +740,9 @@ int spider_db_mysql_result::fetch_table_status(
|
|||||||
("spider auto_increment_value=%lld", auto_increment_value));
|
("spider auto_increment_value=%lld", auto_increment_value));
|
||||||
if (mysql_row[6])
|
if (mysql_row[6])
|
||||||
{
|
{
|
||||||
|
my_time_status_init(&time_status);
|
||||||
str_to_datetime(mysql_row[6], strlen(mysql_row[6]), &mysql_time, 0,
|
str_to_datetime(mysql_row[6], strlen(mysql_row[6]), &mysql_time, 0,
|
||||||
¬_used_int);
|
&time_status);
|
||||||
#ifdef MARIADB_BASE_VERSION
|
#ifdef MARIADB_BASE_VERSION
|
||||||
create_time = (time_t) my_system_gmt_sec(&mysql_time,
|
create_time = (time_t) my_system_gmt_sec(&mysql_time,
|
||||||
¬_used_long, ¬_used_uint);
|
¬_used_long, ¬_used_uint);
|
||||||
@ -759,8 +763,9 @@ int spider_db_mysql_result::fetch_table_status(
|
|||||||
#endif
|
#endif
|
||||||
if (mysql_row[7])
|
if (mysql_row[7])
|
||||||
{
|
{
|
||||||
|
my_time_status_init(&time_status);
|
||||||
str_to_datetime(mysql_row[7], strlen(mysql_row[7]), &mysql_time, 0,
|
str_to_datetime(mysql_row[7], strlen(mysql_row[7]), &mysql_time, 0,
|
||||||
¬_used_int);
|
&time_status);
|
||||||
#ifdef MARIADB_BASE_VERSION
|
#ifdef MARIADB_BASE_VERSION
|
||||||
update_time = (time_t) my_system_gmt_sec(&mysql_time,
|
update_time = (time_t) my_system_gmt_sec(&mysql_time,
|
||||||
¬_used_long, ¬_used_uint);
|
¬_used_long, ¬_used_uint);
|
||||||
@ -781,8 +786,9 @@ int spider_db_mysql_result::fetch_table_status(
|
|||||||
#endif
|
#endif
|
||||||
if (mysql_row[8])
|
if (mysql_row[8])
|
||||||
{
|
{
|
||||||
|
my_time_status_init(&time_status);
|
||||||
str_to_datetime(mysql_row[8], strlen(mysql_row[8]), &mysql_time, 0,
|
str_to_datetime(mysql_row[8], strlen(mysql_row[8]), &mysql_time, 0,
|
||||||
¬_used_int);
|
&time_status);
|
||||||
#ifdef MARIADB_BASE_VERSION
|
#ifdef MARIADB_BASE_VERSION
|
||||||
check_time = (time_t) my_system_gmt_sec(&mysql_time,
|
check_time = (time_t) my_system_gmt_sec(&mysql_time,
|
||||||
¬_used_long, ¬_used_uint);
|
¬_used_long, ¬_used_uint);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user