MDEV-16991 Rounding vs truncation for TIME, DATETIME, TIMESTAMP
This commit is contained in:
parent
27f3329ff6
commit
4447a02cf1
@ -108,12 +108,14 @@ typedef struct st_mysql_time_status
|
|||||||
{
|
{
|
||||||
int warnings;
|
int warnings;
|
||||||
uint precision;
|
uint precision;
|
||||||
|
uint nanoseconds;
|
||||||
} MYSQL_TIME_STATUS;
|
} MYSQL_TIME_STATUS;
|
||||||
|
|
||||||
static inline void my_time_status_init(MYSQL_TIME_STATUS *status)
|
static inline void my_time_status_init(MYSQL_TIME_STATUS *status)
|
||||||
{
|
{
|
||||||
status->warnings= 0;
|
status->warnings= 0;
|
||||||
status->precision= 0;
|
status->precision= 0;
|
||||||
|
status->nanoseconds= 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,
|
||||||
|
1374
mysql-test/main/func_time_round.result
Normal file
1374
mysql-test/main/func_time_round.result
Normal file
File diff suppressed because it is too large
Load Diff
461
mysql-test/main/func_time_round.test
Normal file
461
mysql-test/main/func_time_round.test
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
|
||||||
|
CREATE TABLE t1_datetime_in_varchar (id SERIAL, a VARCHAR(64));
|
||||||
|
INSERT INTO t1_datetime_in_varchar (a) VALUES
|
||||||
|
('2000-12-31 23:59:59'),
|
||||||
|
('2000-12-31 23:59:59.9'),
|
||||||
|
('2000-12-31 23:59:59.99'),
|
||||||
|
('2000-12-31 23:59:59.999'),
|
||||||
|
('2000-12-31 23:59:59.9999'),
|
||||||
|
('2000-12-31 23:59:59.99999'),
|
||||||
|
('2000-12-31 23:59:59.999999'),
|
||||||
|
('2000-12-31 23:59:59.9999999');
|
||||||
|
|
||||||
|
CREATE TABLE t1_datetime_in_decimal (id SERIAL, a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1_datetime_in_decimal (a) VALUES
|
||||||
|
(20001231235959),
|
||||||
|
(20001231235959.9),
|
||||||
|
(20001231235959.99),
|
||||||
|
(20001231235959.999),
|
||||||
|
(20001231235959.9999),
|
||||||
|
(20001231235959.99999),
|
||||||
|
(20001231235959.999999),
|
||||||
|
(20001231235959.9999999);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1_time_in_varchar (id SERIAL, a VARCHAR(64));
|
||||||
|
INSERT INTO t1_time_in_varchar (a) VALUES
|
||||||
|
('00:00:00'),
|
||||||
|
('00:00:00.9'),
|
||||||
|
('00:00:00.99'),
|
||||||
|
('00:00:00.999'),
|
||||||
|
('00:00:00.9999'),
|
||||||
|
('00:00:00.99999'),
|
||||||
|
('00:00:00.999999'),
|
||||||
|
('00:00:00.9999999');
|
||||||
|
INSERT INTO t1_time_in_varchar (a) VALUES
|
||||||
|
('837:59:59.9999999'),
|
||||||
|
('838:59:59'),
|
||||||
|
('838:59:59.9'),
|
||||||
|
('838:59:59.99'),
|
||||||
|
('838:59:59.999'),
|
||||||
|
('838:59:59.9999'),
|
||||||
|
('838:59:59.99999'),
|
||||||
|
('838:59:59.999999'),
|
||||||
|
('838:59:59.9999999'),
|
||||||
|
('839:59:59.9999999'),
|
||||||
|
('87649414:59:59.999999'),
|
||||||
|
('87649414:59:59.9999999'),
|
||||||
|
('87649415:59:59.999999'),
|
||||||
|
('87649415:59:59.9999999');
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1_time_in_decimal (id SERIAL, a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1_time_in_decimal (a) VALUES
|
||||||
|
(0),
|
||||||
|
(0.9),
|
||||||
|
(0.99),
|
||||||
|
(0.999),
|
||||||
|
(0.9999),
|
||||||
|
(0.99999),
|
||||||
|
(0.999999),
|
||||||
|
(0.9999999);
|
||||||
|
INSERT INTO t1_time_in_decimal (a) VALUES
|
||||||
|
(8375959.9999999),
|
||||||
|
(8385959),
|
||||||
|
(8385959.9),
|
||||||
|
(8385959.99),
|
||||||
|
(8385959.999),
|
||||||
|
(8385959.9999),
|
||||||
|
(8385959.99999),
|
||||||
|
(8385959.999999),
|
||||||
|
(8385959.9999999),
|
||||||
|
(8395959.9999999),
|
||||||
|
(876494145959.999999),
|
||||||
|
(876494145959.9999999),
|
||||||
|
(876494155959.999999),
|
||||||
|
(876494155959.9999999);
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # TIME: LEAST/GREATEST
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT GREATEST(TIME'00:00:00', a) FROM t1_time_in_varchar;
|
||||||
|
SELECT GREATEST(TIME'00:00:00', a) FROM t1_time_in_decimal;
|
||||||
|
|
||||||
|
SELECT GREATEST(TIME'00:00:00', '00:00:00.0000004');
|
||||||
|
SELECT GREATEST(TIME'00:00:00', 0.0000004);
|
||||||
|
|
||||||
|
SELECT GREATEST(TIME'00:00:00', '00:00:00.0000005');
|
||||||
|
SELECT GREATEST(TIME'00:00:00', 0.0000005);
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single TIME input, conversion from DATETIME-in-VARCHAR
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT SECOND(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT MINUTE(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT HOUR(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
SELECT EXTRACT(SECOND FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT EXTRACT(MINUTE FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT EXTRACT(HOUR FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
SELECT TIME_TO_SEC(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single TIME input, conversion from DATETIME-in-DECIMAL
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
SELECT SECOND(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT MINUTE(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT HOUR(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
SELECT EXTRACT(SECOND FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT EXTRACT(MINUTE FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT EXTRACT(HOUR FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
SELECT TIME_TO_SEC(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single TIME interval input, conversion from TIME-interval-in-VARCHAR
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
EXTRACT(DAY FROM a),
|
||||||
|
EXTRACT(HOUR FROM a),
|
||||||
|
EXTRACT(MINUTE FROM a),
|
||||||
|
EXTRACT(SECOND FROM a),
|
||||||
|
EXTRACT(MICROSECOND FROM a),
|
||||||
|
CAST(a AS INTERVAL DAY_SECOND(6)),
|
||||||
|
a
|
||||||
|
FROM t1_time_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TIME_TO_SEC(a),
|
||||||
|
CAST(a AS TIME(6)),
|
||||||
|
a
|
||||||
|
FROM t1_time_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single TIME interval input, conversion from TIME-interval-in-DECIMAL
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
EXTRACT(DAY FROM a),
|
||||||
|
EXTRACT(HOUR FROM a),
|
||||||
|
EXTRACT(MINUTE FROM a),
|
||||||
|
EXTRACT(SECOND FROM a),
|
||||||
|
EXTRACT(MICROSECOND FROM a),
|
||||||
|
CAST(a AS INTERVAL DAY_SECOND(6)),
|
||||||
|
a
|
||||||
|
FROM t1_time_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TIME_TO_SEC(a),
|
||||||
|
CAST(a AS TIME(6)),
|
||||||
|
a
|
||||||
|
FROM t1_time_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single DATE input, conversion from DATETIME-in-VARCHAR
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT QUARTER(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT MONTH(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT YEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
SELECT DAYNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT MONTHNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
SELECT LAST_DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT TO_DAYS(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SELECT DAYOFYEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(32));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2002-01-05 23:59:59'),
|
||||||
|
('2002-01-05 23:59:59.999999'),
|
||||||
|
('2002-01-05 23:59:59.9999999');
|
||||||
|
SELECT YEARWEEK(a), a FROM t1;
|
||||||
|
SELECT WEEK(a), a FROM t1;
|
||||||
|
SELECT WEEKDAY(a), a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,9));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(20020105235959),
|
||||||
|
(20020105235959.999999),
|
||||||
|
(20020105235959.9999999);
|
||||||
|
SELECT YEARWEEK(a), a FROM t1;
|
||||||
|
SELECT WEEK(a), a FROM t1;
|
||||||
|
SELECT WEEKDAY(a), a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single DATE input, conversion from DATETIME-in-DECIMAL
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT QUARTER(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT MONTH(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT YEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
SELECT DAYNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT MONTHNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT YEARWEEK(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
SELECT LAST_DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT TO_DAYS(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT DAYOFYEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SELECT DAYOFMONTH(a), CAST(a AS DATE), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single DATETIME input, conversion from DATETIME-in-VARCHAR
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT TO_SECONDS(a), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SELECT UNIX_TIMESTAMP(a), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
SELECT CONVERT_TZ(a, '+00:00','+00:00'), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_varchar ORDER BY id;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with a single DATETIME input, conversion from DATETIME-in-DECIMAL
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT TO_SECONDS(a), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SELECT UNIX_TIMESTAMP(a), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
SELECT CONVERT_TZ(a, '+00:00','+00:00'), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_decimal ORDER BY id;
|
||||||
|
|
||||||
|
DROP TABLE t1_datetime_in_varchar;
|
||||||
|
DROP TABLE t1_datetime_in_decimal;
|
||||||
|
DROP TABLE t1_time_in_varchar;
|
||||||
|
DROP TABLE t1_time_in_decimal;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions that construct DATETIME
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
CREATE TABLE t1_unix_timestamp (id SERIAL, a DECIMAL(30,10));
|
||||||
|
INSERT INTO t1_unix_timestamp (a) VALUES
|
||||||
|
(980639999),
|
||||||
|
(980639999.9),
|
||||||
|
(980639999.999999),
|
||||||
|
(980639999.9999999),
|
||||||
|
(2147483647),
|
||||||
|
(2147483647.9),
|
||||||
|
(2147483647.999999),
|
||||||
|
(2147483647.9999999);
|
||||||
|
SELECT a, FROM_UNIXTIME(a) FROM t1_unix_timestamp ORDER BY id;
|
||||||
|
DROP TABLE t1_unix_timestamp;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions that construct TIME
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1_sec (id SERIAL, a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1_sec (a) VALUES
|
||||||
|
(59),
|
||||||
|
(59.9),
|
||||||
|
(59.999999),
|
||||||
|
(59.9999999),
|
||||||
|
(3020398),
|
||||||
|
(3020398.999999),
|
||||||
|
(3020398.9999999),
|
||||||
|
(3020399),
|
||||||
|
(3020399.999999),
|
||||||
|
(3020399.9999999),
|
||||||
|
(9223372036854775807),
|
||||||
|
(9223372036854775807.9),
|
||||||
|
(9223372036854775807.999999),
|
||||||
|
(9223372036854775807.9999999),
|
||||||
|
(18446744073709551615),
|
||||||
|
(18446744073709551615.9),
|
||||||
|
(18446744073709551615.999999),
|
||||||
|
(18446744073709551615.9999999);
|
||||||
|
SELECT a, SEC_TO_TIME(a) FROM t1_sec ORDER BY id;
|
||||||
|
DROP TABLE t1_sec;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1_sec (id SERIAL, a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1_sec (a) VALUES
|
||||||
|
(0),
|
||||||
|
(0.9),
|
||||||
|
(0.999999),
|
||||||
|
(0.9999999);
|
||||||
|
SELECT a, MAKETIME(0, 0, a) FROM t1_sec ORDER BY id;
|
||||||
|
DROP TABLE t1_sec;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2017-12-31 23:59:59'),
|
||||||
|
('2017-12-31 23:59:59.9'),
|
||||||
|
('2017-12-31 23:59:59.999999'),
|
||||||
|
('2017-12-31 23:59:59.9999999');
|
||||||
|
--vertical_results
|
||||||
|
SELECT
|
||||||
|
'----',
|
||||||
|
a,
|
||||||
|
DATE_FORMAT(a, '%Y') AS yyyy,
|
||||||
|
DATE_FORMAT(a, '%Y-%m-%d') AS d,
|
||||||
|
DATE_FORMAT(a, '%H:%i:%s') AS t0,
|
||||||
|
DATE_FORMAT(a, '%H:%i:%s.%f') AS t6,
|
||||||
|
DATE_FORMAT(a, '%Y-%m-%d %H:%i:%s') AS dt0,
|
||||||
|
DATE_FORMAT(a, '%Y-%m-%d %H:%i:%s.%f') AS dt6
|
||||||
|
FROM t1;
|
||||||
|
--horizontal_results
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,9));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(20171231235959),
|
||||||
|
(20171231235959.9),
|
||||||
|
(20171231235959.999999),
|
||||||
|
(20171231235959.9999999);
|
||||||
|
--vertical_results
|
||||||
|
SELECT
|
||||||
|
'----',
|
||||||
|
a,
|
||||||
|
DATE_FORMAT(a, '%Y') AS yyyy,
|
||||||
|
DATE_FORMAT(a, '%Y-%m-%d') AS d,
|
||||||
|
DATE_FORMAT(a, '%H:%i:%s') AS t0,
|
||||||
|
DATE_FORMAT(a, '%H:%i:%s.%f') AS t6,
|
||||||
|
DATE_FORMAT(a, '%Y-%m-%d %H:%i:%s') AS dt0,
|
||||||
|
DATE_FORMAT(a, '%Y-%m-%d %H:%i:%s.%f') AS dt6
|
||||||
|
FROM t1;
|
||||||
|
--horizontal_results
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Functions with two temporal parameters that round nanoseconds in both parameters in MySQL
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
CREATE TABLE t2 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2017-12-31 23:59:59'),
|
||||||
|
('2017-12-31 23:59:59.9'),
|
||||||
|
('2017-12-31 23:59:59.999999'),
|
||||||
|
('2017-12-31 23:59:59.9999999');
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
('00:00:00'),
|
||||||
|
('00:00:00.9'),
|
||||||
|
('00:00:00.999999'),
|
||||||
|
('00:00:00.9999999');
|
||||||
|
|
||||||
|
SELECT TIMESTAMP(t1.a, t2.a), t1.a, t2.a FROM t1,t2 ORDER BY t1.a, t2.a;
|
||||||
|
SELECT ADDTIME(t1.a, t2.a), t1.a, t2.a FROM t1,t2 ORDER BY t1.a, t2.a;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
CREATE TABLE t2 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('23:59:59'),
|
||||||
|
('23:59:59.9'),
|
||||||
|
('23:59:59.999999'),
|
||||||
|
('23:59:59.9999999');
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
('00:00:00'),
|
||||||
|
('00:00:00.9'),
|
||||||
|
('00:00:00.999999'),
|
||||||
|
('00:00:00.9999999');
|
||||||
|
SELECT TIMEDIFF(t1.a, t2.a), t1.a, t2.a FROM t1,t2 ORDER BY t1.a, t2.a;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
CREATE TABLE t2 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2001-12-31 23:59:59'),
|
||||||
|
('2001-12-31 23:59:59.9'),
|
||||||
|
('2001-12-31 23:59:59.999999'),
|
||||||
|
('2001-12-31 23:59:59.9999999');
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
('2001-12-31 23:59:59'),
|
||||||
|
('2001-12-31 23:59:59.9'),
|
||||||
|
('2001-12-31 23:59:59.999999'),
|
||||||
|
('2001-12-31 23:59:59.9999999');
|
||||||
|
SELECT TIMESTAMPDIFF(MICROSECOND,t1.a, t2.a), t1.a, t2.a FROM t1,t2 ORDER BY t1.a, t2.a;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
CREATE TABLE t2 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('23:59:59'),
|
||||||
|
('23:59:59.9'),
|
||||||
|
('23:59:59.999999'),
|
||||||
|
('23:59:59.9999999');
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
('00:00:00'),
|
||||||
|
('00:00:00.9'),
|
||||||
|
('00:00:00.999999'),
|
||||||
|
('00:00:00.9999999');
|
||||||
|
SELECT TIMEDIFF(t1.a, t2.a), t1.a, t2.a FROM t1,t2 ORDER BY t1.a, t2.a;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # STR_TO_DATE behaviour is questionable in MySQL 5.6 (MySQL Bug #92474)
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo # It truncates nanoseconds, but this may change in the future.
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2017-12-31 23:59:59'),
|
||||||
|
('2017-12-31 23:59:59.9'),
|
||||||
|
('2017-12-31 23:59:59.999999'),
|
||||||
|
('2017-12-31 23:59:59.9999999');
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
a,
|
||||||
|
STR_TO_DATE(a, '%Y-%m-%d %H:%i:%s') AS c0,
|
||||||
|
STR_TO_DATE(a, '%Y-%m-%d %H:%i:%s.%f') AS c6
|
||||||
|
FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATE_ADD behaviour is questionable in MySQL 5.6 (MySQL Bug#92473)
|
||||||
|
--echo # It rounds nanoseconds in the first argument, but truncates nanoseconds in the second argument.
|
||||||
|
--echo # This may change in the future, to round both arguments.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('2017-12-31 23:59:59'),
|
||||||
|
('2017-12-31 23:59:59.9'),
|
||||||
|
('2017-12-31 23:59:59.999999'),
|
||||||
|
('2017-12-31 23:59:59.9999999');
|
||||||
|
CREATE TABLE t2 (b DECIMAL(32,9));
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(0),
|
||||||
|
(0.9),
|
||||||
|
(0.999999),
|
||||||
|
(0.9999999);
|
||||||
|
SELECT a, b, DATE_ADD(a, INTERVAL b SECOND) FROM t1,t2 ORDER BY a,b;
|
||||||
|
DROP TABLE t1, t2;
|
@ -664,7 +664,7 @@ proc body longblob
|
|||||||
proc definer char(141)
|
proc definer char(141)
|
||||||
proc created timestamp
|
proc created timestamp
|
||||||
proc modified timestamp
|
proc modified timestamp
|
||||||
proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
|
proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL')
|
||||||
proc comment text
|
proc comment text
|
||||||
proc character_set_client char(32)
|
proc character_set_client char(32)
|
||||||
proc collation_connection char(32)
|
proc collation_connection char(32)
|
||||||
|
@ -1209,7 +1209,8 @@ The following specify which files/extra groups are read (specified before remain
|
|||||||
ERROR_FOR_DIVISION_BY_ZERO, TRADITIONAL,
|
ERROR_FOR_DIVISION_BY_ZERO, TRADITIONAL,
|
||||||
NO_AUTO_CREATE_USER, HIGH_NOT_PRECEDENCE,
|
NO_AUTO_CREATE_USER, HIGH_NOT_PRECEDENCE,
|
||||||
NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH,
|
NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH,
|
||||||
EMPTY_STRING_IS_NULL, SIMULTANEOUS_ASSIGNMENT
|
EMPTY_STRING_IS_NULL, SIMULTANEOUS_ASSIGNMENT,
|
||||||
|
TIME_ROUND_FRACTIONAL
|
||||||
--sql-safe-updates If set to 1, UPDATEs and DELETEs need either a key in the
|
--sql-safe-updates If set to 1, UPDATEs and DELETEs need either a key in the
|
||||||
WHERE clause, or a LIMIT clause, or else they will
|
WHERE clause, or a LIMIT clause, or else they will
|
||||||
aborted. Prevents the common mistake of accidentally
|
aborted. Prevents the common mistake of accidentally
|
||||||
|
@ -476,10 +476,14 @@ select @@sql_mode;
|
|||||||
@@sql_mode
|
@@sql_mode
|
||||||
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_TABLE_OPTIONS,ANSI
|
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_TABLE_OPTIONS,ANSI
|
||||||
set sql_mode=2147483648*2*2*2;
|
set sql_mode=2147483648*2*2*2;
|
||||||
ERROR 42000: Variable 'sql_mode' can't be set to the value of '17179869184'
|
|
||||||
select @@sql_mode;
|
select @@sql_mode;
|
||||||
@@sql_mode
|
@@sql_mode
|
||||||
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_TABLE_OPTIONS,ANSI
|
TIME_ROUND_FRACTIONAL
|
||||||
|
set sql_mode=2147483648*2*2*2*2;
|
||||||
|
ERROR 42000: Variable 'sql_mode' can't be set to the value of '34359738368'
|
||||||
|
select @@sql_mode;
|
||||||
|
@@sql_mode
|
||||||
|
TIME_ROUND_FRACTIONAL
|
||||||
set sql_mode=PAD_CHAR_TO_FULL_LENGTH;
|
set sql_mode=PAD_CHAR_TO_FULL_LENGTH;
|
||||||
create table t1 (a int auto_increment primary key, b char(5));
|
create table t1 (a int auto_increment primary key, b char(5));
|
||||||
insert into t1 (b) values('a'),('b\t'),('c ');
|
insert into t1 (b) values('a'),('b\t'),('c ');
|
||||||
|
@ -263,8 +263,10 @@ set sql_mode=4194304;
|
|||||||
select @@sql_mode;
|
select @@sql_mode;
|
||||||
set sql_mode=16384+(65536*4);
|
set sql_mode=16384+(65536*4);
|
||||||
select @@sql_mode;
|
select @@sql_mode;
|
||||||
|
set sql_mode=2147483648*2*2*2;
|
||||||
|
select @@sql_mode;
|
||||||
--error 1231
|
--error 1231
|
||||||
set sql_mode=2147483648*2*2*2; # that mode does not exist
|
set sql_mode=2147483648*2*2*2*2; # that mode does not exist
|
||||||
select @@sql_mode;
|
select @@sql_mode;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -191,7 +191,7 @@ proc CREATE TABLE `proc` (
|
|||||||
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||||
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
@ -217,7 +217,7 @@ event CREATE TABLE `event` (
|
|||||||
`ends` datetime DEFAULT NULL,
|
`ends` datetime DEFAULT NULL,
|
||||||
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
||||||
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`originator` int(10) unsigned NOT NULL,
|
`originator` int(10) unsigned NOT NULL,
|
||||||
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
||||||
|
@ -192,7 +192,7 @@ proc CREATE TABLE `proc` (
|
|||||||
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||||
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
@ -218,7 +218,7 @@ event CREATE TABLE `event` (
|
|||||||
`ends` datetime DEFAULT NULL,
|
`ends` datetime DEFAULT NULL,
|
||||||
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
||||||
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`originator` int(10) unsigned NOT NULL,
|
`originator` int(10) unsigned NOT NULL,
|
||||||
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
||||||
|
@ -192,7 +192,7 @@ proc CREATE TABLE `proc` (
|
|||||||
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||||
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
@ -218,7 +218,7 @@ event CREATE TABLE `event` (
|
|||||||
`ends` datetime DEFAULT NULL,
|
`ends` datetime DEFAULT NULL,
|
||||||
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
||||||
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`originator` int(10) unsigned NOT NULL,
|
`originator` int(10) unsigned NOT NULL,
|
||||||
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
||||||
|
@ -192,7 +192,7 @@ proc CREATE TABLE `proc` (
|
|||||||
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
`created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||||
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
`comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||||
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
|
||||||
@ -218,7 +218,7 @@ event CREATE TABLE `event` (
|
|||||||
`ends` datetime DEFAULT NULL,
|
`ends` datetime DEFAULT NULL,
|
||||||
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
|
||||||
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
|
||||||
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') NOT NULL DEFAULT '',
|
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') NOT NULL DEFAULT '',
|
||||||
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
|
||||||
`originator` int(10) unsigned NOT NULL,
|
`originator` int(10) unsigned NOT NULL,
|
||||||
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',
|
||||||
|
174
mysql-test/main/type_date_round.result
Normal file
174
mysql-test/main/type_date_round.result
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
#
|
||||||
|
# DATE: SET
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATE, b DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATE, b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2000-12-31
|
||||||
|
2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATE, b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2000-12-31
|
||||||
|
2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# DATE: ALTER
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATE;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATE;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999'
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2000-12-31
|
||||||
|
2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a DATE;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2000-12-31
|
||||||
|
2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# DATE: CAST
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
SELECT a, CAST(a AS DATE) FROM t1;
|
||||||
|
a CAST(a AS DATE)
|
||||||
|
2000-12-31 23:59:59.9999 2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
SELECT a, CAST(a AS DATE) FROM t1;
|
||||||
|
a CAST(a AS DATE)
|
||||||
|
2000-12-31 23:59:59.9999 2000-12-31
|
||||||
|
2000-12-31 23:59:59.9999999 2000-12-31
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
SELECT a, CAST(a AS DATE) FROM t1;
|
||||||
|
a CAST(a AS DATE)
|
||||||
|
20001231235959.9999000000 2000-12-31
|
||||||
|
20001231235959.9999999000 2000-12-31
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Equal field propagation
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATE);
|
||||||
|
INSERT INTO t1 VALUES (20010101);
|
||||||
|
INSERT INTO t1 VALUES (20010102);
|
||||||
|
SELECT * FROM t1 WHERE a= 20010101235959.9999999;
|
||||||
|
a
|
||||||
|
2001-01-02
|
||||||
|
SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999';
|
||||||
|
a
|
||||||
|
2001-01-02
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND a>='2001-01-01 23:59:59.9999999';
|
||||||
|
a
|
||||||
|
2001-01-02
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND CONCAT(a)='2001-01-02';
|
||||||
|
a
|
||||||
|
2001-01-02
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND a>='2001-01-01 23:59:59.9999999';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2001-01-02'
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND CONCAT(a)='2001-01-02';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2001-01-02'
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Comparing non-temporal to DATE
|
||||||
|
#
|
||||||
|
# Although conversion from non-temporal to DATE (e.g. on SET) does not round,
|
||||||
|
# comparison between non-temporal to DATE is performed as DATETIME.
|
||||||
|
# So rounding does happen here.
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('2001-01-01 23:59:59.9999999');
|
||||||
|
SELECT * FROM t1 WHERE a=DATE'2001-01-02';
|
||||||
|
a
|
||||||
|
2001-01-01 23:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE CONCAT(a)=DATE'2001-01-02';
|
||||||
|
a
|
||||||
|
2001-01-01 23:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=DATE'2001-01-02';
|
||||||
|
a
|
||||||
|
2001-01-01 23:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (20010101235959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=DATE'2001-01-02';
|
||||||
|
a
|
||||||
|
20010101235959.9999999
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=DATE'2001-01-02';
|
||||||
|
a
|
||||||
|
20010101235959.9999999
|
||||||
|
DROP TABLE t1;
|
113
mysql-test/main/type_date_round.test
Normal file
113
mysql-test/main/type_date_round.test
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATE: SET
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATE, b DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATE, b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATE, b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATE: ALTER
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATE;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATE;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a DATE;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATE: CAST
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
SELECT a, CAST(a AS DATE) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# This truncates microseconds but rounds nanoseconds (MySQL Bug #92475)
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
SELECT a, CAST(a AS DATE) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# This truncates microseconds but rounds nanoseconds (MySQL Bug #92475)
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
SELECT a, CAST(a AS DATE) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Equal field propagation
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATE);
|
||||||
|
INSERT INTO t1 VALUES (20010101);
|
||||||
|
INSERT INTO t1 VALUES (20010102);
|
||||||
|
# DATE is compared to non-temporal as DATETIME
|
||||||
|
# In the below queries nanoseconds should round to microseconds
|
||||||
|
SELECT * FROM t1 WHERE a= 20010101235959.9999999;
|
||||||
|
SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999';
|
||||||
|
SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND a>='2001-01-01 23:59:59.9999999';
|
||||||
|
SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND CONCAT(a)='2001-01-02';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND a>='2001-01-01 23:59:59.9999999';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 23:59:59.9999999' AND CONCAT(a)='2001-01-02';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Comparing non-temporal to DATE
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo # Although conversion from non-temporal to DATE (e.g. on SET) does not round,
|
||||||
|
--echo # comparison between non-temporal to DATE is performed as DATETIME.
|
||||||
|
--echo # So rounding does happen here.
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('2001-01-01 23:59:59.9999999');
|
||||||
|
SELECT * FROM t1 WHERE a=DATE'2001-01-02';
|
||||||
|
SELECT * FROM t1 WHERE CONCAT(a)=DATE'2001-01-02';
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=DATE'2001-01-02';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (20010101235959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=DATE'2001-01-02';
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=DATE'2001-01-02';
|
||||||
|
DROP TABLE t1;
|
205
mysql-test/main/type_datetime_round.result
Normal file
205
mysql-test/main/type_datetime_round.result
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
#
|
||||||
|
# DATETIME: SET
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATETIME(3), b DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATETIME(3), b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DATETIME(3), b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# DATETIME: ALTER
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(3);
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999'
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Corner case:
|
||||||
|
# ALTER DATETIME to a shorter DATETIME
|
||||||
|
# All values round, maximum possible value truncates.
|
||||||
|
#
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
CREATE TABLE t1 (ID INT, a DATETIME(6), comment VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES (0, '9999-12-30 23:59:58.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (1, '9999-12-31 22:59:59.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (2, '9999-12-31 23:59:58.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (3, '9999-12-31 23:59:59.999999', 'Should truncate');
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(5);
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value for column 'a' at row 4
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ID a comment
|
||||||
|
0 9999-12-30 23:59:59.00000 Should round
|
||||||
|
1 9999-12-31 23:00:00.00000 Should round
|
||||||
|
2 9999-12-31 23:59:59.00000 Should round
|
||||||
|
3 9999-12-31 23:59:59.99999 Should truncate
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
#
|
||||||
|
# NOW
|
||||||
|
#
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
CREATE OR REPLACE TABLE t1 (id SERIAL, a DATETIME(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIMESTAMP(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIME(6));
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id a
|
||||||
|
1 2011-01-01 00:00:00.0000
|
||||||
|
2 2011-01-01 00:00:00.0000
|
||||||
|
3 2011-01-01 00:00:00.0000
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
#
|
||||||
|
# DATETIME: CAST
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
SELECT a, CAST(a AS DATETIME(3)) FROM t1;
|
||||||
|
a CAST(a AS DATETIME(3))
|
||||||
|
2000-12-31 23:59:59.9999 2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
SELECT a, CAST(a AS DATETIME(3)) FROM t1;
|
||||||
|
a CAST(a AS DATETIME(3))
|
||||||
|
2000-12-31 23:59:59.9999 2001-01-01 00:00:00.000
|
||||||
|
2000-12-31 23:59:59.9999999 2001-01-01 00:00:00.000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
SELECT a, CAST(a AS DATETIME(3)) FROM t1;
|
||||||
|
a CAST(a AS DATETIME(3))
|
||||||
|
20001231235959.9999000000 2001-01-01 00:00:00.000
|
||||||
|
20001231235959.9999999000 2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Equal field propagation
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a DATETIME(6));
|
||||||
|
INSERT INTO t1 VALUES (20010101235959.999999);
|
||||||
|
INSERT INTO t1 VALUES (20010101235959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=20010101235959.9999999;
|
||||||
|
a
|
||||||
|
2001-01-02 00:00:00.000000
|
||||||
|
SELECT * FROM t1 WHERE a='20010101235959.9999999';
|
||||||
|
a
|
||||||
|
2001-01-02 00:00:00.000000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '20010101235959.9999999'
|
||||||
|
SELECT * FROM t1 WHERE a='20010101235959.9999999' AND a>='20010101235959.9999999';
|
||||||
|
a
|
||||||
|
2001-01-02 00:00:00.000000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '20010101235959.9999999'
|
||||||
|
Note 1292 Truncated incorrect datetime value: '20010101235959.9999999'
|
||||||
|
SELECT * FROM t1 WHERE a='20010101235959.9999999' AND CONCAT(a)='2001-01-02 00:00:00.000000';
|
||||||
|
a
|
||||||
|
2001-01-02 00:00:00.000000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '20010101235959.9999999'
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='20010101235959.9999999' AND a>='20010101235959.9999999';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '20010101235959.9999999'
|
||||||
|
Note 1292 Truncated incorrect datetime value: '20010101235959.9999999'
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-02 00:00:00'
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='20010101235959.9999999' AND CONCAT(a)='2001-01-02 00:00:00.000000';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '20010101235959.9999999'
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-02 00:00:00'
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Comparing non-temporal to DATETIME
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('2001-01-01 23:59:59.9999999');
|
||||||
|
SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
a
|
||||||
|
2001-01-01 23:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE CONCAT(a)=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
a
|
||||||
|
2001-01-01 23:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
a
|
||||||
|
2001-01-01 23:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (20010101235959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
a
|
||||||
|
20010101235959.9999999
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
a
|
||||||
|
20010101235959.9999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Literal corner case
|
||||||
|
#
|
||||||
|
SELECT TIMESTAMP'9999-12-31 23:59:59.999999';
|
||||||
|
TIMESTAMP'9999-12-31 23:59:59.999999'
|
||||||
|
9999-12-31 23:59:59.999999
|
||||||
|
SELECT TIME'9999-12-31 23:59:59.9999999';
|
||||||
|
ERROR HY000: Incorrect TIME value: '9999-12-31 23:59:59.9999999'
|
147
mysql-test/main/type_datetime_round.test
Normal file
147
mysql-test/main/type_datetime_round.test
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATETIME: SET
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(3), b DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(3), b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(3), b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATETIME: ALTER
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Corner case:
|
||||||
|
--echo # ALTER DATETIME to a shorter DATETIME
|
||||||
|
--echo # All values round, maximum possible value truncates.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
CREATE TABLE t1 (ID INT, a DATETIME(6), comment VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES (0, '9999-12-30 23:59:58.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (1, '9999-12-31 22:59:59.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (2, '9999-12-31 23:59:58.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (3, '9999-12-31 23:59:59.999999', 'Should truncate');
|
||||||
|
ALTER TABLE t1 MODIFY a DATETIME(5);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # NOW
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
CREATE OR REPLACE TABLE t1 (id SERIAL, a DATETIME(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIMESTAMP(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIME(6));
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATETIME: CAST
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(4));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
SELECT a, CAST(a AS DATETIME(3)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
SELECT a, CAST(a AS DATETIME(3)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
SELECT a, CAST(a AS DATETIME(3)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Equal field propagation
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DATETIME(6));
|
||||||
|
INSERT INTO t1 VALUES (20010101235959.999999);
|
||||||
|
INSERT INTO t1 VALUES (20010101235959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=20010101235959.9999999;
|
||||||
|
SELECT * FROM t1 WHERE a='20010101235959.9999999';
|
||||||
|
SELECT * FROM t1 WHERE a='20010101235959.9999999' AND a>='20010101235959.9999999';
|
||||||
|
SELECT * FROM t1 WHERE a='20010101235959.9999999' AND CONCAT(a)='2001-01-02 00:00:00.000000';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='20010101235959.9999999' AND a>='20010101235959.9999999';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='20010101235959.9999999' AND CONCAT(a)='2001-01-02 00:00:00.000000';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Comparing non-temporal to DATETIME
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('2001-01-01 23:59:59.9999999');
|
||||||
|
SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
SELECT * FROM t1 WHERE CONCAT(a)=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (20010101235959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIMESTAMP'2001-01-02 00:00:00';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Literal corner case
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT TIMESTAMP'9999-12-31 23:59:59.999999';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'9999-12-31 23:59:59.9999999';
|
260
mysql-test/main/type_time_round.result
Normal file
260
mysql-test/main/type_time_round.result
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
#
|
||||||
|
# TIME: SET
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TIME(3), b TIME(4));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIME(3), b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIME(3), b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIME(3), b DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIME(6), b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIME(6), b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIME(6), b DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# TIME: ALTER
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TIME(4));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '00:00:00.9999999'
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
00:00:01.000
|
||||||
|
00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# TIME: CAST
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TIME(4));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
a CAST(a AS TIME(3))
|
||||||
|
00:00:00.9999 00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999999');
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
a CAST(a AS TIME(3))
|
||||||
|
00:00:00.9999 00:00:01.000
|
||||||
|
00:00:00.9999999 00:00:01.000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '00:00:00.9999999'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
a CAST(a AS TIME(3))
|
||||||
|
0.9999000000 00:00:01.000
|
||||||
|
0.9999999000 00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
a CAST(a AS TIME(3))
|
||||||
|
0.9999 00:00:01.000
|
||||||
|
0.9999999 00:00:01.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999999');
|
||||||
|
SELECT a, CAST(a AS TIME(6)) FROM t1;
|
||||||
|
a CAST(a AS TIME(6))
|
||||||
|
00:00:00.9999999 00:00:01.000000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '00:00:00.9999999'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(6)) FROM t1;
|
||||||
|
a CAST(a AS TIME(6))
|
||||||
|
0.9999999000 00:00:01.000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(6)) FROM t1;
|
||||||
|
a CAST(a AS TIME(6))
|
||||||
|
0.9999999 00:00:01.000000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# NOW
|
||||||
|
#
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
CREATE OR REPLACE TABLE t1 (id SERIAL, a TIME(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIMESTAMP(6));
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIME(6));
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id a
|
||||||
|
1 24:00:00.0000
|
||||||
|
2 24:00:00.0000
|
||||||
|
3 24:00:00.0000
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
#
|
||||||
|
# Equal field propagation
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TIME(6));
|
||||||
|
INSERT INTO t1 VALUES (0.999999);
|
||||||
|
INSERT INTO t1 VALUES (0.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=0.9999999;
|
||||||
|
a
|
||||||
|
00:00:01.000000
|
||||||
|
SELECT * FROM t1 WHERE a='0.9999999';
|
||||||
|
a
|
||||||
|
00:00:01.000000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '0.9999999'
|
||||||
|
SELECT * FROM t1 WHERE a='0.9999999' AND a>='0.9999999';
|
||||||
|
a
|
||||||
|
00:00:01.000000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '0.9999999'
|
||||||
|
Note 1292 Truncated incorrect time value: '0.9999999'
|
||||||
|
SELECT * FROM t1 WHERE a='0.9999999' AND CONCAT(a)='00:00:01.000000';
|
||||||
|
a
|
||||||
|
00:00:01.000000
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '0.9999999'
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0.9999999' AND a>='0.9999999';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '0.9999999'
|
||||||
|
Note 1292 Truncated incorrect time value: '0.9999999'
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:01'
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0.9999999' AND CONCAT(a)='00:00:01.000000';
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '0.9999999'
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:01'
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Comparing non-temporal to TIME
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('22:59:59.9999999');
|
||||||
|
SELECT * FROM t1 WHERE a=TIME'23:00:00';
|
||||||
|
a
|
||||||
|
22:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '22:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE CONCAT(a)=TIME'23:00:00';
|
||||||
|
a
|
||||||
|
22:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '22:59:59.9999999'
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIME'23:00:00';
|
||||||
|
a
|
||||||
|
22:59:59.9999999
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect time value: '22:59:59.9999999'
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (225959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=TIME'23:00:00';
|
||||||
|
a
|
||||||
|
225959.9999999
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIME'23:00:00';
|
||||||
|
a
|
||||||
|
225959.9999999
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Literal corner case
|
||||||
|
#
|
||||||
|
SELECT TIME'838:59:59.999999';
|
||||||
|
TIME'838:59:59.999999'
|
||||||
|
838:59:59.999999
|
||||||
|
SELECT TIME'838:59:59.9999999';
|
||||||
|
ERROR HY000: Incorrect TIME value: '838:59:59.9999999'
|
||||||
|
SELECT TIME'839:00:00';
|
||||||
|
ERROR HY000: Incorrect TIME value: '839:00:00'
|
184
mysql-test/main/type_time_round.test
Normal file
184
mysql-test/main/type_time_round.test
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # TIME: SET
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(3), b TIME(4));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(3), b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(3), b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(3), b DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(6), b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'00:00:00.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(6), b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(6), b DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(NULL,0.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # TIME: ALTER
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(4));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a TIME(3);
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # TIME: CAST
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(4));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999');
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999999');
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(0.9999);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(3)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('00:00:00.9999999');
|
||||||
|
SELECT a, CAST(a AS TIME(6)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(6)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DOUBLE);
|
||||||
|
INSERT INTO t1 VALUES(0.9999999);
|
||||||
|
SELECT a, CAST(a AS TIME(6)) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # NOW
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
CREATE OR REPLACE TABLE t1 (id SERIAL, a TIME(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIMESTAMP(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIME(6));
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Equal field propagation
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIME(6));
|
||||||
|
INSERT INTO t1 VALUES (0.999999);
|
||||||
|
INSERT INTO t1 VALUES (0.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=0.9999999;
|
||||||
|
SELECT * FROM t1 WHERE a='0.9999999';
|
||||||
|
SELECT * FROM t1 WHERE a='0.9999999' AND a>='0.9999999';
|
||||||
|
SELECT * FROM t1 WHERE a='0.9999999' AND CONCAT(a)='00:00:01.000000';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0.9999999' AND a>='0.9999999';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0.9999999' AND CONCAT(a)='00:00:01.000000';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Comparing non-temporal to TIME
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('22:59:59.9999999');
|
||||||
|
SELECT * FROM t1 WHERE a=TIME'23:00:00';
|
||||||
|
SELECT * FROM t1 WHERE CONCAT(a)=TIME'23:00:00';
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIME'23:00:00';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (225959.9999999);
|
||||||
|
SELECT * FROM t1 WHERE a=TIME'23:00:00';
|
||||||
|
SELECT * FROM t1 WHERE COALESCE(a)=TIME'23:00:00';
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Literal corner case
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SELECT TIME'838:59:59.999999';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'838:59:59.9999999';
|
||||||
|
--error ER_WRONG_VALUE
|
||||||
|
SELECT TIME'839:00:00';
|
164
mysql-test/main/type_timestamp_round.result
Normal file
164
mysql-test/main/type_timestamp_round.result
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
#
|
||||||
|
# TIMESTAMP: SET
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(3) NULL DEFAULT NULL, b TIMESTAMP(4) NULL DEFAULT NULL);
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(3) NULL DEFAULT NULL, b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 2
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(3) NULL DEFAULT NULL, b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# TIMESTAMP: ALTER
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(4) NULL DEFAULT NULL);
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(3) NULL DEFAULT NULL;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(3) NULL DEFAULT NULL;
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999'
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(3) NULL DEFAULT NULL;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
a
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
2001-01-01 00:00:00.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Corner case:
|
||||||
|
# ALTER TIMESTAMP to a shorter TIMESTAMP
|
||||||
|
# All values round, maximum possible value truncates.
|
||||||
|
#
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should truncate');
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(5);
|
||||||
|
Warnings:
|
||||||
|
Warning 1264 Out of range value for column 'a' at row 3
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ID a comment
|
||||||
|
0 2038-01-19 00:00:00.00000 Should round
|
||||||
|
1 2038-01-19 03:14:07.00000 Should round
|
||||||
|
2 2038-01-19 03:14:07.99999 Should truncate
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
#
|
||||||
|
# NOW
|
||||||
|
#
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
CREATE OR REPLACE TABLE t1 (id SERIAL, a TIMESTAMP(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIMESTAMP(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIME(6));
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id a
|
||||||
|
1 2011-01-01 00:00:00.0000
|
||||||
|
2 2011-01-01 00:00:00.0000
|
||||||
|
3 2011-01-01 00:00:00.0000
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
#
|
||||||
|
# DATETIME to TIMESTAMP conversion with DST change
|
||||||
|
#
|
||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%',
|
||||||
|
'STRICT_ALL_TABLES,TIME_ROUND_FRACTIONAL',
|
||||||
|
'STRICT_ALL_TABLES');
|
||||||
|
SET time_zone='Europe/Moscow';
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP);
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.0' /* Winter time */);
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.9' /* Rounds to the DST gap */);
|
||||||
|
ERROR 22007: Incorrect datetime value: '2010-03-28 01:59:59.9' for column 'a' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a
|
||||||
|
2010-03-28 01:59:59
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
SET sql_mode=@default_sql_mode;
|
||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%','TIME_ROUND_FRACTIONAL','');
|
||||||
|
SET time_zone='Europe/Moscow';
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP);
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.0' /* Winter time */);
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.9' /* Rounds to the DST gap, then gets fixed to the first second of the summer time */);
|
||||||
|
Warnings:
|
||||||
|
Warning 1299 Invalid TIMESTAMP value in column 'a' at row 1
|
||||||
|
SELECT a, UNIX_TIMESTAMP(a) FROM t1;
|
||||||
|
a UNIX_TIMESTAMP(a)
|
||||||
|
2010-03-28 01:59:59 1269730799
|
||||||
|
2010-03-28 03:00:00 1269730800
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
SET sql_mode=@default_sql_mode;
|
||||||
|
#
|
||||||
|
# Comparing non-temporal to TIMESTAMP
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('2001-01-01 23:59:59.9999999');
|
||||||
|
CREATE TABLE t2 (a TIMESTAMP);
|
||||||
|
INSERT INTO t2 VALUES ('2001-01-02 00:00:00');
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=t2.a;
|
||||||
|
a a
|
||||||
|
2001-01-01 23:59:59.9999999 2001-01-02 00:00:00
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1,t2 WHERE CONCAT(t1.a)=t2.a;
|
||||||
|
a a
|
||||||
|
2001-01-01 23:59:59.9999999 2001-01-02 00:00:00
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
SELECT * FROM t1,t2 WHERE COALESCE(t1.a)=t2.a;
|
||||||
|
a a
|
||||||
|
2001-01-01 23:59:59.9999999 2001-01-02 00:00:00
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-01-01 23:59:59.9999999'
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (20010101235959.9999999);
|
||||||
|
CREATE TABLE t2 (a TIMESTAMP);
|
||||||
|
INSERT INTO t2 VALUES ('2001-01-02 00:00:00');
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=t2.a;
|
||||||
|
a a
|
||||||
|
20010101235959.9999999 2001-01-02 00:00:00
|
||||||
|
SELECT * FROM t1,t2 WHERE COALESCE(t1.a)=t2.a;
|
||||||
|
a a
|
||||||
|
20010101235959.9999999 2001-01-02 00:00:00
|
||||||
|
DROP TABLE t1,t2;
|
138
mysql-test/main/type_timestamp_round.test
Normal file
138
mysql-test/main/type_timestamp_round.test
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%', 'TIME_ROUND_FRACTIONAL', '');
|
||||||
|
SET @default_sql_mode=@@sql_mode;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # TIMESTAMP: SET
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(3) NULL DEFAULT NULL, b TIMESTAMP(4) NULL DEFAULT NULL);
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(3) NULL DEFAULT NULL, b VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES(NULL,'2000-12-31 23:59:59.9999999');
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(3) NULL DEFAULT NULL, b DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(NULL,20001231235959.9999999);
|
||||||
|
UPDATE t1 SET a=b;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # TIMESTAMP: ALTER
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(4) NULL DEFAULT NULL);
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(3) NULL DEFAULT NULL;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999');
|
||||||
|
INSERT INTO t1 VALUES('2000-12-31 23:59:59.9999999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(3) NULL DEFAULT NULL;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(38,10));
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999);
|
||||||
|
INSERT INTO t1 VALUES(20001231235959.9999999);
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(3) NULL DEFAULT NULL;
|
||||||
|
SELECT a FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Corner case:
|
||||||
|
--echo # ALTER TIMESTAMP to a shorter TIMESTAMP
|
||||||
|
--echo # All values round, maximum possible value truncates.
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
CREATE TABLE t1 (ID INT, a TIMESTAMP(6), comment VARCHAR(64));
|
||||||
|
INSERT INTO t1 VALUES (0, '2038-01-18 23:59:59.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (1, '2038-01-19 03:14:06.999999', 'Should round');
|
||||||
|
INSERT INTO t1 VALUES (2, '2038-01-19 03:14:07.999999', 'Should truncate');
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(5);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # NOW
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
CREATE OR REPLACE TABLE t1 (id SERIAL, a TIMESTAMP(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIMESTAMP(6));
|
||||||
|
INSERT INTO t1 (a) VALUES (CURRENT_TIME(6));
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # DATETIME to TIMESTAMP conversion with DST change
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%',
|
||||||
|
'STRICT_ALL_TABLES,TIME_ROUND_FRACTIONAL',
|
||||||
|
'STRICT_ALL_TABLES');
|
||||||
|
--enable_warnings
|
||||||
|
SET time_zone='Europe/Moscow';
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP);
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.0' /* Winter time */);
|
||||||
|
--error ER_TRUNCATED_WRONG_VALUE
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.9' /* Rounds to the DST gap */);
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
--disable_warnings
|
||||||
|
SET sql_mode=@default_sql_mode;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
SET sql_mode=IF(@@version LIKE '%MariaDB%','TIME_ROUND_FRACTIONAL','');
|
||||||
|
SET time_zone='Europe/Moscow';
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP);
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.0' /* Winter time */);
|
||||||
|
INSERT INTO t1 VALUES ('2010-03-28 01:59:59.9' /* Rounds to the DST gap, then gets fixed to the first second of the summer time */);
|
||||||
|
SELECT a, UNIX_TIMESTAMP(a) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
--disable_warnings
|
||||||
|
SET sql_mode=@default_sql_mode;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Comparing non-temporal to TIMESTAMP
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(64));
|
||||||
|
INSERT t1 VALUES ('2001-01-01 23:59:59.9999999');
|
||||||
|
CREATE TABLE t2 (a TIMESTAMP);
|
||||||
|
INSERT INTO t2 VALUES ('2001-01-02 00:00:00');
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=t2.a;
|
||||||
|
SELECT * FROM t1,t2 WHERE CONCAT(t1.a)=t2.a;
|
||||||
|
SELECT * FROM t1,t2 WHERE COALESCE(t1.a)=t2.a;
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a DECIMAL(32,7));
|
||||||
|
INSERT t1 VALUES (20010101235959.9999999);
|
||||||
|
CREATE TABLE t2 (a TIMESTAMP);
|
||||||
|
INSERT INTO t2 VALUES ('2001-01-02 00:00:00');
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=t2.a;
|
||||||
|
SELECT * FROM t1,t2 WHERE COALESCE(t1.a)=t2.a;
|
||||||
|
DROP TABLE t1,t2;
|
@ -61,7 +61,7 @@ def mysql event modified 9 '0000-00-00 00:00:00' NO timestamp NULL NULL NULL NUL
|
|||||||
def mysql event name 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references NEVER NULL
|
def mysql event name 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references NEVER NULL
|
||||||
def mysql event on_completion 14 'DROP' NO enum 8 24 NULL NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references NEVER NULL
|
def mysql event on_completion 14 'DROP' NO enum 8 24 NULL NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references NEVER NULL
|
||||||
def mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references NEVER NULL
|
def mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references NEVER NULL
|
||||||
def mysql event sql_mode 15 '' NO set 539 1617 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') select,insert,update,references NEVER NULL
|
def mysql event sql_mode 15 '' NO set 561 1683 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') select,insert,update,references NEVER NULL
|
||||||
def mysql event starts 11 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references NEVER NULL
|
def mysql event starts 11 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select,insert,update,references NEVER NULL
|
||||||
def mysql event status 13 'ENABLED' NO enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references NEVER NULL
|
def mysql event status 13 'ENABLED' NO enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references NEVER NULL
|
||||||
def mysql event time_zone 18 'SYSTEM' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references NEVER NULL
|
def mysql event time_zone 18 'SYSTEM' NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references NEVER NULL
|
||||||
@ -133,7 +133,7 @@ def mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL
|
|||||||
def mysql proc security_type 8 'DEFINER' NO enum 7 21 NULL NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references NEVER NULL
|
def mysql proc security_type 8 'DEFINER' NO enum 7 21 NULL NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references NEVER NULL
|
||||||
def mysql proc specific_name 4 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL
|
def mysql proc specific_name 4 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL
|
||||||
def mysql proc sql_data_access 6 'CONTAINS_SQL' NO enum 17 51 NULL NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references NEVER NULL
|
def mysql proc sql_data_access 6 'CONTAINS_SQL' NO enum 17 51 NULL NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references NEVER NULL
|
||||||
def mysql proc sql_mode 15 '' NO set 539 1617 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') select,insert,update,references NEVER NULL
|
def mysql proc sql_mode 15 '' NO set 561 1683 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') select,insert,update,references NEVER NULL
|
||||||
def mysql proc type 3 NULL NO enum 12 36 NULL NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE','PACKAGE','PACKAGE BODY') PRI select,insert,update,references NEVER NULL
|
def mysql proc type 3 NULL NO enum 12 36 NULL NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE','PACKAGE','PACKAGE BODY') PRI select,insert,update,references NEVER NULL
|
||||||
def mysql procs_priv Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NEVER NULL
|
def mysql procs_priv Db 2 '' NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NEVER NULL
|
||||||
def mysql procs_priv Grantor 6 '' NO char 141 423 NULL NULL NULL utf8 utf8_bin char(141) MUL select,insert,update,references NEVER NULL
|
def mysql procs_priv Grantor 6 '' NO char 141 423 NULL NULL NULL utf8 utf8_bin char(141) MUL select,insert,update,references NEVER NULL
|
||||||
@ -380,7 +380,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime
|
|||||||
NULL mysql event ends datetime NULL NULL NULL NULL datetime
|
NULL mysql event ends datetime NULL NULL NULL NULL datetime
|
||||||
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
|
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
|
||||||
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
|
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
|
||||||
3.0000 mysql event sql_mode set 539 1617 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
|
3.0000 mysql event sql_mode set 561 1683 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL')
|
||||||
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
|
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
|
||||||
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
|
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
|
||||||
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
|
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
|
||||||
@ -451,7 +451,7 @@ NULL mysql innodb_table_stats sum_of_other_index_sizes bigint NULL NULL NULL NUL
|
|||||||
3.0000 mysql proc definer char 141 423 utf8 utf8_bin char(141)
|
3.0000 mysql proc definer char 141 423 utf8 utf8_bin char(141)
|
||||||
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
|
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
|
||||||
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
|
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
|
||||||
3.0000 mysql proc sql_mode set 539 1617 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')
|
3.0000 mysql proc sql_mode set 561 1683 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL')
|
||||||
1.0000 mysql proc comment text 65535 65535 utf8 utf8_bin text
|
1.0000 mysql proc comment text 65535 65535 utf8 utf8_bin text
|
||||||
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
|
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
|
||||||
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
|
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
|
||||||
|
50
mysql-test/suite/rpl/r/rpl_temporal_round.result
Normal file
50
mysql-test/suite/rpl/r/rpl_temporal_round.result
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
include/master-slave.inc
|
||||||
|
[connection master]
|
||||||
|
SET sql_mode=TIME_ROUND_FRACTIONAL;
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
CREATE TABLE t1 (id SERIAL, a TIMESTAMP(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t1 (a) VALUES ('2011-01-01 23:59:59.999999');
|
||||||
|
CREATE TABLE t2 (id SERIAL, a DATETIME(4));
|
||||||
|
INSERT INTO t2 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t2 (a) VALUES ('2011-01-01 23:59:59.999999');
|
||||||
|
CREATE TABLE t3 (id SERIAL, a TIME(4));
|
||||||
|
INSERT INTO t3 (a) VALUES (now(6));
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
INSERT INTO t3 (a) VALUES ('2011-01-01 23:59:59.999999');
|
||||||
|
Warnings:
|
||||||
|
Note 1265 Data truncated for column 'a' at row 1
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id a
|
||||||
|
1 2011-01-01 00:00:00.0000
|
||||||
|
2 2011-01-02 00:00:00.0000
|
||||||
|
SELECT * FROM t2;
|
||||||
|
id a
|
||||||
|
1 2011-01-01 00:00:00.0000
|
||||||
|
2 2011-01-02 00:00:00.0000
|
||||||
|
SELECT * FROM t3;
|
||||||
|
id a
|
||||||
|
1 24:00:00.0000
|
||||||
|
2 24:00:00.0000
|
||||||
|
connection slave;
|
||||||
|
connection slave;
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SELECT * FROM t1;
|
||||||
|
id a
|
||||||
|
1 2011-01-01 00:00:00.0000
|
||||||
|
2 2011-01-02 00:00:00.0000
|
||||||
|
SELECT * FROM t2;
|
||||||
|
id a
|
||||||
|
1 2011-01-01 00:00:00.0000
|
||||||
|
2 2011-01-02 00:00:00.0000
|
||||||
|
SELECT * FROM t3;
|
||||||
|
id a
|
||||||
|
1 24:00:00.0000
|
||||||
|
2 24:00:00.0000
|
||||||
|
connection master;
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t3;
|
||||||
|
include/rpl_end.inc
|
35
mysql-test/suite/rpl/t/rpl_temporal_round.test
Normal file
35
mysql-test/suite/rpl/t/rpl_temporal_round.test
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
--source include/master-slave.inc
|
||||||
|
|
||||||
|
SET sql_mode=TIME_ROUND_FRACTIONAL;
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2010-12-31 23:59:59.999999');
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id SERIAL, a TIMESTAMP(4));
|
||||||
|
INSERT INTO t1 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t1 (a) VALUES ('2011-01-01 23:59:59.999999');
|
||||||
|
|
||||||
|
CREATE TABLE t2 (id SERIAL, a DATETIME(4));
|
||||||
|
INSERT INTO t2 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t2 (a) VALUES ('2011-01-01 23:59:59.999999');
|
||||||
|
|
||||||
|
CREATE TABLE t3 (id SERIAL, a TIME(4));
|
||||||
|
INSERT INTO t3 (a) VALUES (now(6));
|
||||||
|
INSERT INTO t3 (a) VALUES ('2011-01-01 23:59:59.999999');
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t3;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection slave;
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SELECT * FROM t1;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
SELECT * FROM t3;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE t3;
|
||||||
|
|
||||||
|
--source include/rpl_end.inc
|
@ -367,7 +367,15 @@ SELECT @@global.sql_mode;
|
|||||||
@@global.sql_mode
|
@@global.sql_mode
|
||||||
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT
|
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT
|
||||||
SET @@global.sql_mode = 17179869184;
|
SET @@global.sql_mode = 17179869184;
|
||||||
ERROR 42000: Variable 'sql_mode' can't be set to the value of '17179869184'
|
SELECT @@global.sql_mode;
|
||||||
|
@@global.sql_mode
|
||||||
|
TIME_ROUND_FRACTIONAL
|
||||||
|
SET @@global.sql_mode = 34359738367;
|
||||||
|
SELECT @@global.sql_mode;
|
||||||
|
@@global.sql_mode
|
||||||
|
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT,TIME_ROUND_FRACTIONAL
|
||||||
|
SET @@global.sql_mode = 34359738368;
|
||||||
|
ERROR 42000: Variable 'sql_mode' can't be set to the value of '34359738368'
|
||||||
SET @@global.sql_mode = 0.4;
|
SET @@global.sql_mode = 0.4;
|
||||||
ERROR 42000: Incorrect argument type to variable 'sql_mode'
|
ERROR 42000: Incorrect argument type to variable 'sql_mode'
|
||||||
'#---------------------FN_DYNVARS_152_08----------------------#'
|
'#---------------------FN_DYNVARS_152_08----------------------#'
|
||||||
|
@ -4755,7 +4755,7 @@ VARIABLE_COMMENT Sets the sql mode
|
|||||||
NUMERIC_MIN_VALUE NULL
|
NUMERIC_MIN_VALUE NULL
|
||||||
NUMERIC_MAX_VALUE NULL
|
NUMERIC_MAX_VALUE NULL
|
||||||
NUMERIC_BLOCK_SIZE NULL
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
ENUM_VALUE_LIST REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT
|
ENUM_VALUE_LIST REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH,EMPTY_STRING_IS_NULL,SIMULTANEOUS_ASSIGNMENT,TIME_ROUND_FRACTIONAL
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
VARIABLE_NAME SQL_NOTES
|
VARIABLE_NAME SQL_NOTES
|
||||||
|
@ -310,8 +310,14 @@ SELECT @@global.sql_mode;
|
|||||||
SET @@global.sql_mode = 17179869183;
|
SET @@global.sql_mode = 17179869183;
|
||||||
SELECT @@global.sql_mode;
|
SELECT @@global.sql_mode;
|
||||||
|
|
||||||
--Error ER_WRONG_VALUE_FOR_VAR
|
|
||||||
SET @@global.sql_mode = 17179869184;
|
SET @@global.sql_mode = 17179869184;
|
||||||
|
SELECT @@global.sql_mode;
|
||||||
|
|
||||||
|
SET @@global.sql_mode = 34359738367;
|
||||||
|
SELECT @@global.sql_mode;
|
||||||
|
|
||||||
|
--Error ER_WRONG_VALUE_FOR_VAR
|
||||||
|
SET @@global.sql_mode = 34359738368;
|
||||||
|
|
||||||
# use of decimal values
|
# use of decimal values
|
||||||
|
|
||||||
|
@ -130,3 +130,14 @@ show status like "Feature_system_versioning";
|
|||||||
Variable_name Value
|
Variable_name Value
|
||||||
Feature_system_versioning 2
|
Feature_system_versioning 2
|
||||||
drop table t;
|
drop table t;
|
||||||
|
#
|
||||||
|
# MDEV-16991 Rounding vs truncation for TIME, DATETIME, TIMESTAMP
|
||||||
|
#
|
||||||
|
SET sql_mode=TIME_ROUND_FRACTIONAL;
|
||||||
|
SET @@global.system_versioning_asof= timestamp'2001-12-31 23:59:59.9999999';
|
||||||
|
Warnings:
|
||||||
|
Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999'
|
||||||
|
SELECT @@global.system_versioning_asof;
|
||||||
|
@@global.system_versioning_asof
|
||||||
|
2002-01-01 00:00:00.000000
|
||||||
|
SET @@global.system_versioning_asof= DEFAULT;
|
||||||
|
@ -87,3 +87,13 @@ select * from t for system_time between '0-0-0' and current_timestamp(6);
|
|||||||
show status like "Feature_system_versioning";
|
show status like "Feature_system_versioning";
|
||||||
|
|
||||||
drop table t;
|
drop table t;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16991 Rounding vs truncation for TIME, DATETIME, TIMESTAMP
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET sql_mode=TIME_ROUND_FRACTIONAL;
|
||||||
|
SET @@global.system_versioning_asof= timestamp'2001-12-31 23:59:59.9999999';
|
||||||
|
SELECT @@global.system_versioning_asof;
|
||||||
|
SET @@global.system_versioning_asof= DEFAULT;
|
||||||
|
@ -80,7 +80,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=Aria transactional=1 CHARACTER SET utf8 comment='Leap seconds information for time zones';
|
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=Aria transactional=1 CHARACTER SET utf8 comment='Leap seconds information for time zones';
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE','PACKAGE','PACKAGE BODY') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob NOT NULL, body longblob NOT NULL, definer char(141) collate utf8_bin DEFAULT '' NOT NULL, created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH', 'EMPTY_STRING_IS_NULL', 'SIMULTANEOUS_ASSIGNMENT') DEFAULT '' NOT NULL, comment text collate utf8_bin NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, aggregate enum('NONE', 'GROUP') DEFAULT 'NONE' NOT NULL, PRIMARY KEY (db,name,type)) engine=Aria transactional=1 character set utf8 comment='Stored Procedures';
|
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE','PACKAGE','PACKAGE BODY') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob NOT NULL, body longblob NOT NULL, definer char(141) collate utf8_bin DEFAULT '' NOT NULL, created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH', 'EMPTY_STRING_IS_NULL', 'SIMULTANEOUS_ASSIGNMENT', 'TIME_ROUND_FRACTIONAL') DEFAULT '' NOT NULL, comment text collate utf8_bin NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, aggregate enum('NONE', 'GROUP') DEFAULT 'NONE' NOT NULL, PRIMARY KEY (db,name,type)) engine=Aria transactional=1 character set utf8 comment='Stored Procedures';
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE','PACKAGE','PACKAGE BODY') NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
|
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE','PACKAGE','PACKAGE BODY') NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ PREPARE stmt FROM @str;
|
|||||||
EXECUTE stmt;
|
EXECUTE stmt;
|
||||||
DROP PREPARE stmt;
|
DROP PREPARE stmt;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) engine=Aria transactional=1 DEFAULT CHARSET=utf8 COMMENT 'Events';
|
CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, modified TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH','EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT','TIME_ROUND_FRACTIONAL') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) engine=Aria transactional=1 DEFAULT CHARSET=utf8 COMMENT 'Events';
|
||||||
|
|
||||||
SET @create_innodb_table_stats="CREATE TABLE IF NOT EXISTS innodb_table_stats (
|
SET @create_innodb_table_stats="CREATE TABLE IF NOT EXISTS innodb_table_stats (
|
||||||
database_name VARCHAR(64) NOT NULL,
|
database_name VARCHAR(64) NOT NULL,
|
||||||
|
@ -417,7 +417,8 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
|
|||||||
'NO_ENGINE_SUBSTITUTION',
|
'NO_ENGINE_SUBSTITUTION',
|
||||||
'PAD_CHAR_TO_FULL_LENGTH',
|
'PAD_CHAR_TO_FULL_LENGTH',
|
||||||
'EMPTY_STRING_IS_NULL',
|
'EMPTY_STRING_IS_NULL',
|
||||||
'SIMULTANEOUS_ASSIGNMENT'
|
'SIMULTANEOUS_ASSIGNMENT',
|
||||||
|
'TIME_ROUND_FRACTIONAL'
|
||||||
) DEFAULT '' NOT NULL,
|
) DEFAULT '' NOT NULL,
|
||||||
DEFAULT CHARACTER SET utf8;
|
DEFAULT CHARACTER SET utf8;
|
||||||
|
|
||||||
@ -553,7 +554,8 @@ ALTER TABLE event MODIFY sql_mode
|
|||||||
'NO_ENGINE_SUBSTITUTION',
|
'NO_ENGINE_SUBSTITUTION',
|
||||||
'PAD_CHAR_TO_FULL_LENGTH',
|
'PAD_CHAR_TO_FULL_LENGTH',
|
||||||
'EMPTY_STRING_IS_NULL',
|
'EMPTY_STRING_IS_NULL',
|
||||||
'SIMULTANEOUS_ASSIGNMENT'
|
'SIMULTANEOUS_ASSIGNMENT',
|
||||||
|
'TIME_ROUND_FRACTIONAL'
|
||||||
) DEFAULT '' NOT NULL AFTER on_completion;
|
) DEFAULT '' NOT NULL AFTER on_completion;
|
||||||
ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default '';
|
ALTER TABLE event MODIFY name char(64) CHARACTER SET utf8 NOT NULL default '';
|
||||||
|
|
||||||
|
@ -256,6 +256,14 @@ static void get_microseconds(ulong *val, MYSQL_TIME_STATUS *status,
|
|||||||
*val= (ulong) (tmp * log_10_int[6 - (*str - start)]);
|
*val= (ulong) (tmp * log_10_int[6 - (*str - start)]);
|
||||||
else
|
else
|
||||||
*val= tmp;
|
*val= tmp;
|
||||||
|
if (str[0] < end && my_isdigit(&my_charset_latin1, str[0][0]))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We don't need the exact nanoseconds value.
|
||||||
|
Knowing the first digit is enough for rounding.
|
||||||
|
*/
|
||||||
|
status->nanoseconds= 100 * (uint)(str[0][0] - '0');
|
||||||
|
}
|
||||||
if (skip_digits(str, end))
|
if (skip_digits(str, end))
|
||||||
status->warnings|= MYSQL_TIME_NOTE_TRUNCATED;
|
status->warnings|= MYSQL_TIME_NOTE_TRUNCATED;
|
||||||
}
|
}
|
||||||
|
@ -479,14 +479,24 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
|
|||||||
uint not_used;
|
uint not_used;
|
||||||
if (!starts_null)
|
if (!starts_null)
|
||||||
{
|
{
|
||||||
table->field[ET_FIELD_STARTS]->get_date(&time, TIME_NO_ZERO_DATE);
|
/*
|
||||||
|
The expected data type for these columns in mysql.events:
|
||||||
|
starts, ends, execute_at, last_executed
|
||||||
|
is DATETIME. No nanosecond truncation should normally be needed,
|
||||||
|
unless the DBA changes them, e.g. to VARCHAR, DECIMAL, etc.
|
||||||
|
For this unexpected case let's use the default round mode,
|
||||||
|
according to the current session settings.
|
||||||
|
*/
|
||||||
|
table->field[ET_FIELD_STARTS]->get_date(&time, TIME_NO_ZERO_DATE |
|
||||||
|
thd->temporal_round_mode());
|
||||||
starts= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
starts= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
ends_null= table->field[ET_FIELD_ENDS]->is_null();
|
ends_null= table->field[ET_FIELD_ENDS]->is_null();
|
||||||
if (!ends_null)
|
if (!ends_null)
|
||||||
{
|
{
|
||||||
table->field[ET_FIELD_ENDS]->get_date(&time, TIME_NO_ZERO_DATE);
|
table->field[ET_FIELD_ENDS]->get_date(&time, TIME_NO_ZERO_DATE |
|
||||||
|
thd->temporal_round_mode());
|
||||||
ends= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
ends= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,8 +512,8 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
|
|||||||
DBUG_ASSERT(!(starts_null && ends_null && !expression && execute_at_null));
|
DBUG_ASSERT(!(starts_null && ends_null && !expression && execute_at_null));
|
||||||
if (!expression && !execute_at_null)
|
if (!expression && !execute_at_null)
|
||||||
{
|
{
|
||||||
if (table->field[ET_FIELD_EXECUTE_AT]->get_date(&time,
|
if (table->field[ET_FIELD_EXECUTE_AT]->get_date(&time, TIME_NO_ZERO_DATE |
|
||||||
TIME_NO_ZERO_DATE))
|
thd->temporal_round_mode()))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
execute_at= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
execute_at= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
||||||
}
|
}
|
||||||
@ -535,8 +545,8 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
|
|||||||
|
|
||||||
if (!table->field[ET_FIELD_LAST_EXECUTED]->is_null())
|
if (!table->field[ET_FIELD_LAST_EXECUTED]->is_null())
|
||||||
{
|
{
|
||||||
table->field[ET_FIELD_LAST_EXECUTED]->get_date(&time,
|
table->field[ET_FIELD_LAST_EXECUTED]->get_date(&time, TIME_NO_ZERO_DATE |
|
||||||
TIME_NO_ZERO_DATE);
|
thd->temporal_round_mode());
|
||||||
last_executed= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
last_executed= my_tz_OFFSET0->TIME_to_gmt_sec(&time,¬_used);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,13 @@ Event_parse_data::init_execute_at(THD *thd)
|
|||||||
(starts_null && ends_null)));
|
(starts_null && ends_null)));
|
||||||
DBUG_ASSERT(starts_null && ends_null);
|
DBUG_ASSERT(starts_null && ends_null);
|
||||||
|
|
||||||
if (item_execute_at->get_date(thd, <ime, TIME_NO_ZERO_DATE))
|
/*
|
||||||
|
The expected data type is DATETIME. No nanoseconds truncation should
|
||||||
|
normally be needed. Using the default rounding mode.
|
||||||
|
See more comments in event_data_object.cc.
|
||||||
|
*/
|
||||||
|
if (item_execute_at->get_date(thd, <ime, TIME_NO_ZERO_DATE |
|
||||||
|
thd->temporal_round_mode()))
|
||||||
goto wrong_value;
|
goto wrong_value;
|
||||||
|
|
||||||
ltime_utc= TIME_to_timestamp(thd,<ime,¬_used);
|
ltime_utc= TIME_to_timestamp(thd,<ime,¬_used);
|
||||||
@ -378,7 +384,8 @@ Event_parse_data::init_starts(THD *thd)
|
|||||||
if (item_starts->fix_fields(thd, &item_starts))
|
if (item_starts->fix_fields(thd, &item_starts))
|
||||||
goto wrong_value;
|
goto wrong_value;
|
||||||
|
|
||||||
if (item_starts->get_date(thd, <ime, TIME_NO_ZERO_DATE))
|
if (item_starts->get_date(thd, <ime, TIME_NO_ZERO_DATE |
|
||||||
|
thd->temporal_round_mode()))
|
||||||
goto wrong_value;
|
goto wrong_value;
|
||||||
|
|
||||||
ltime_utc= TIME_to_timestamp(thd, <ime, ¬_used);
|
ltime_utc= TIME_to_timestamp(thd, <ime, ¬_used);
|
||||||
@ -433,7 +440,8 @@ Event_parse_data::init_ends(THD *thd)
|
|||||||
goto error_bad_params;
|
goto error_bad_params;
|
||||||
|
|
||||||
DBUG_PRINT("info", ("convert to TIME"));
|
DBUG_PRINT("info", ("convert to TIME"));
|
||||||
if (item_ends->get_date(thd, <ime, TIME_NO_ZERO_DATE))
|
if (item_ends->get_date(thd, <ime, TIME_NO_ZERO_DATE |
|
||||||
|
thd->temporal_round_mode()))
|
||||||
goto error_bad_params;
|
goto error_bad_params;
|
||||||
|
|
||||||
ltime_utc= TIME_to_timestamp(thd, <ime, ¬_used);
|
ltime_utc= TIME_to_timestamp(thd, <ime, ¬_used);
|
||||||
|
149
sql/field.cc
149
sql/field.cc
@ -5084,10 +5084,11 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
date_mode_t Field_timestamp::sql_mode_for_timestamp(THD *thd) const
|
date_conv_mode_t Timestamp::sql_mode_for_timestamp(THD *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
|
||||||
return date_mode_t((thd->variables.sql_mode & MODE_NO_ZERO_DATE) | MODE_NO_ZERO_IN_DATE);
|
return date_conv_mode_t((thd->variables.sql_mode & MODE_NO_ZERO_DATE) |
|
||||||
|
MODE_NO_ZERO_IN_DATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5096,7 +5097,7 @@ int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec)
|
|||||||
int warn;
|
int warn;
|
||||||
ErrConvTime str(ltime);
|
ErrConvTime str(ltime);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Datetime dt(thd, &warn, ltime, sql_mode_for_timestamp(thd), decimals());
|
Datetime dt(thd, &warn, ltime, Timestamp::DatetimeOptions(thd), decimals());
|
||||||
return store_TIME_with_warning(thd, &dt, &str, warn);
|
return store_TIME_with_warning(thd, &dt, &str, warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5106,7 +5107,7 @@ int Field_timestamp::store(const char *from,size_t len,CHARSET_INFO *cs)
|
|||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
MYSQL_TIME_STATUS st;
|
MYSQL_TIME_STATUS st;
|
||||||
Datetime dt(&st, from, len, cs, sql_mode_for_timestamp(thd), decimals());
|
Datetime dt(thd, &st, from, len, cs, Timestamp::DatetimeOptions(thd), decimals());
|
||||||
return store_TIME_with_warning(thd, &dt, &str, st.warnings);
|
return store_TIME_with_warning(thd, &dt, &str, st.warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5116,7 +5117,7 @@ int Field_timestamp::store(double nr)
|
|||||||
int error;
|
int error;
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Datetime dt(&error, nr, sql_mode_for_timestamp(thd), decimals());
|
Datetime dt(thd, &error, nr, Timestamp::DatetimeOptions(thd), decimals());
|
||||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5127,14 +5128,29 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
|
|||||||
Longlong_hybrid tmp(nr, unsigned_val);
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
ErrConvInteger str(tmp);
|
ErrConvInteger str(tmp);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Datetime dt(&error, tmp, sql_mode_for_timestamp(thd));
|
Datetime dt(thd, &error, tmp, Timestamp::DatetimeOptions(thd));
|
||||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part)
|
int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part)
|
||||||
{
|
{
|
||||||
store_TIMESTAMP(Timestamp(ts, sec_part).trunc(decimals()));
|
int warn= 0;
|
||||||
|
time_round_mode_t mode= Datetime::default_round_mode(get_thd());
|
||||||
|
store_TIMESTAMP(Timestamp(ts, sec_part).round(decimals(), mode, &warn));
|
||||||
|
if (warn)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We're here if rounding would overflow outside of the supported TIMESTAMP
|
||||||
|
range, so truncation happened instead:
|
||||||
|
CREATE TABLE t1 (a TIMESTAMP(6));
|
||||||
|
INSERT INTO t1 VALUES ('maximum-possible-timestamp.999999');
|
||||||
|
ALTER TABLE t1 MODIFY a TIMESTAMP(5);
|
||||||
|
SELECT * FROM t1; --> 'maximum-possible-timestamp.99999' (5 digits)
|
||||||
|
Raise a warning, like DATETIME does for '9999-12-31 23:59:59.999999'.
|
||||||
|
*/
|
||||||
|
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
|
}
|
||||||
if (ts == 0 && sec_part == 0 &&
|
if (ts == 0 && sec_part == 0 &&
|
||||||
get_thd()->variables.sql_mode & (ulonglong) TIME_NO_ZERO_DATE)
|
get_thd()->variables.sql_mode & (ulonglong) TIME_NO_ZERO_DATE)
|
||||||
{
|
{
|
||||||
@ -5157,7 +5173,7 @@ double Field_timestamp::val_real(void)
|
|||||||
longlong Field_timestamp::val_int(void)
|
longlong Field_timestamp::val_int(void)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
if (get_date(<ime, TIME_NO_ZERO_DATE))
|
if (get_date(<ime, Datetime::Options(TIME_NO_ZERO_DATE, get_thd())))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ltime.year * 10000000000LL + ltime.month * 100000000LL +
|
return ltime.year * 10000000000LL + ltime.month * 100000000LL +
|
||||||
@ -5177,7 +5193,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
|
|||||||
to= (char*) val_buffer->ptr();
|
to= (char*) val_buffer->ptr();
|
||||||
val_buffer->length(field_length);
|
val_buffer->length(field_length);
|
||||||
|
|
||||||
if (get_date(<ime, TIME_NO_ZERO_DATE))
|
if (get_date(<ime, Datetime::Options(TIME_NO_ZERO_DATE, get_thd())))
|
||||||
{ /* Zero time is "000000" */
|
{ /* Zero time is "000000" */
|
||||||
val_ptr->set(zero_timestamp, field_length, &my_charset_numeric);
|
val_ptr->set(zero_timestamp, field_length, &my_charset_numeric);
|
||||||
return val_ptr;
|
return val_ptr;
|
||||||
@ -5407,7 +5423,7 @@ my_time_t Field_timestamp_hires::get_timestamp(const uchar *pos,
|
|||||||
double Field_timestamp_with_dec::val_real(void)
|
double Field_timestamp_with_dec::val_real(void)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
if (get_date(<ime, TIME_NO_ZERO_DATE))
|
if (get_date(<ime, Datetime::Options(TIME_NO_ZERO_DATE, get_thd())))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return ltime.year * 1e10 + ltime.month * 1e8 +
|
return ltime.year * 1e10 + ltime.month * 1e8 +
|
||||||
@ -5427,7 +5443,7 @@ int Field_timestamp::store_decimal(const my_decimal *d)
|
|||||||
int error;
|
int error;
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
Datetime dt(&error, d, sql_mode_for_timestamp(thd), decimals());
|
Datetime dt(thd, &error, d, Timestamp::DatetimeOptions(thd), decimals());
|
||||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5570,7 +5586,8 @@ int Field_datetime::store(const char *from, size_t len, CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
MYSQL_TIME_STATUS st;
|
MYSQL_TIME_STATUS st;
|
||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
Datetime dt(&st, from, len, cs, sql_mode_for_dates(get_thd()), decimals());
|
THD *thd= get_thd();
|
||||||
|
Datetime dt(thd, &st, from, len, cs, Datetime::Options(thd), decimals());
|
||||||
return store_TIME_with_warning(&dt, &str, st.warnings);
|
return store_TIME_with_warning(&dt, &str, st.warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5578,7 +5595,8 @@ int Field_datetime::store(double nr)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
Datetime dt(&error, nr, sql_mode_for_dates(get_thd()), decimals());
|
THD *thd= get_thd();
|
||||||
|
Datetime dt(thd, &error, nr, Datetime::Options(thd), decimals());
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5588,7 +5606,8 @@ int Field_datetime::store(longlong nr, bool unsigned_val)
|
|||||||
int error;
|
int error;
|
||||||
Longlong_hybrid tmp(nr, unsigned_val);
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
ErrConvInteger str(tmp);
|
ErrConvInteger str(tmp);
|
||||||
Datetime dt(&error, tmp, sql_mode_for_dates(get_thd()));
|
THD *thd= get_thd();
|
||||||
|
Datetime dt(thd, &error, tmp, Datetime::Options(thd));
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5597,7 +5616,7 @@ int Field_datetime::store_time_dec(const MYSQL_TIME *ltime, uint dec)
|
|||||||
int error;
|
int error;
|
||||||
ErrConvTime str(ltime);
|
ErrConvTime str(ltime);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Datetime dt(thd, &error, ltime, sql_mode_for_dates(thd), decimals());
|
Datetime dt(thd, &error, ltime, Datetime::Options(thd), decimals());
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5606,7 +5625,8 @@ int Field_datetime::store_decimal(const my_decimal *d)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
Datetime tm(&error, d, sql_mode_for_dates(get_thd()), decimals());
|
THD *thd= get_thd();
|
||||||
|
Datetime tm(thd, &error, d, Datetime::Options(thd), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, error);
|
return store_TIME_with_warning(&tm, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5617,7 +5637,7 @@ Field_temporal_with_date::validate_value_in_record(THD *thd,
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(!is_null_in_record(record));
|
DBUG_ASSERT(!is_null_in_record(record));
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
return get_TIME(<ime, ptr_in_record(record), sql_mode_for_dates(thd));
|
return get_TIME(<ime, ptr_in_record(record), Datetime::Options(thd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5657,7 +5677,8 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
|
|||||||
const_item->field_type() != MYSQL_TYPE_TIMESTAMP) ||
|
const_item->field_type() != MYSQL_TYPE_TIMESTAMP) ||
|
||||||
const_item->decimals != decimals())
|
const_item->decimals != decimals())
|
||||||
{
|
{
|
||||||
Datetime dt(thd, const_item, date_mode_t(0));
|
Datetime::Options opt(TIME_CONV_NONE, thd);
|
||||||
|
Datetime dt(thd, const_item, opt, decimals());
|
||||||
if (!dt.is_valid_datetime())
|
if (!dt.is_valid_datetime())
|
||||||
return NULL;
|
return NULL;
|
||||||
/*
|
/*
|
||||||
@ -5672,7 +5693,7 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
|
|||||||
case ANY_SUBST:
|
case ANY_SUBST:
|
||||||
if (!is_temporal_type_with_date(const_item->field_type()))
|
if (!is_temporal_type_with_date(const_item->field_type()))
|
||||||
{
|
{
|
||||||
Datetime dt(thd, const_item, Datetime::comparison_flags_for_get_date());
|
Datetime dt(thd, const_item, Datetime::Options_cmp(thd));
|
||||||
if (!dt.is_valid_datetime())
|
if (!dt.is_valid_datetime())
|
||||||
return NULL;
|
return NULL;
|
||||||
return new (thd->mem_root)
|
return new (thd->mem_root)
|
||||||
@ -5724,7 +5745,17 @@ int Field_time::store(const char *from,size_t len,CHARSET_INFO *cs)
|
|||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
MYSQL_TIME_STATUS st;
|
MYSQL_TIME_STATUS st;
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Time tm(thd, &st, from, len, cs, sql_mode_for_dates(thd), decimals());
|
/*
|
||||||
|
Unlike number-to-time conversion, we need to additionally pass
|
||||||
|
MODE_NO_ZERO_DATE here (if it presents in the current sql_mode):
|
||||||
|
SET sql_mode='STRICT_ALL_TABLES,NO_ZERO_DATE';
|
||||||
|
INSERT INTO t1 VALUES ('0000-00-00 00:00:00'); -- error
|
||||||
|
INSERT INTO t1 VALUES (0); -- ok
|
||||||
|
In the first INSERT we have a zero date.
|
||||||
|
In the second INSERT we don't have a zero date (it is just a zero time).
|
||||||
|
*/
|
||||||
|
Time::Options opt(sql_mode_for_dates(thd), thd);
|
||||||
|
Time tm(thd, &st, from, len, cs, opt, decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, st.warnings);
|
return store_TIME_with_warning(&tm, &str, st.warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5733,7 +5764,7 @@ int Field_time::store_time_dec(const MYSQL_TIME *ltime, uint dec)
|
|||||||
{
|
{
|
||||||
ErrConvTime str(ltime);
|
ErrConvTime str(ltime);
|
||||||
int warn;
|
int warn;
|
||||||
Time tm(&warn, ltime, curdays, decimals());
|
Time tm(&warn, ltime, curdays, Time::Options(get_thd()), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, warn);
|
return store_TIME_with_warning(&tm, &str, warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5742,7 +5773,7 @@ int Field_time::store(double nr)
|
|||||||
{
|
{
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
int was_cut;
|
int was_cut;
|
||||||
Time tm(get_thd(), &was_cut, nr, Time::Options(), decimals());
|
Time tm(get_thd(), &was_cut, nr, Time::Options(get_thd()), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5752,8 +5783,14 @@ int Field_time::store(longlong nr, bool unsigned_val)
|
|||||||
Longlong_hybrid tmp(nr, unsigned_val);
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
ErrConvInteger str(tmp);
|
ErrConvInteger str(tmp);
|
||||||
int was_cut;
|
int was_cut;
|
||||||
// Need fractional digit truncation if nr overflows to '838:59:59.999999'
|
THD *thd= get_thd();
|
||||||
Time tm(get_thd(), &was_cut, tmp, Time::Options(), decimals());
|
/*
|
||||||
|
Need fractional digit truncation if nr overflows to '838:59:59.999999'.
|
||||||
|
The constructor used below will always truncate (never round).
|
||||||
|
We don't need to care to overwrite the default session rounding mode
|
||||||
|
from HALF_UP to TRUNCATE.
|
||||||
|
*/
|
||||||
|
Time tm(thd, &was_cut, tmp, Time::Options(thd), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5805,7 +5842,7 @@ String *Field_time::val_str(String *str,
|
|||||||
{
|
{
|
||||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
get_date(<ime, TIME_TIME_ONLY);
|
get_date(<ime, Datetime::Options(TIME_TIME_ONLY, get_thd()));
|
||||||
str->alloc(field_length + 1);
|
str->alloc(field_length + 1);
|
||||||
str->length(my_time_to_str(<ime, const_cast<char*>(str->ptr()), decimals()));
|
str->length(my_time_to_str(<ime, const_cast<char*>(str->ptr()), decimals()));
|
||||||
str->set_charset(&my_charset_numeric);
|
str->set_charset(&my_charset_numeric);
|
||||||
@ -5815,7 +5852,8 @@ String *Field_time::val_str(String *str,
|
|||||||
|
|
||||||
bool Field_time::check_zero_in_date_with_warn(date_mode_t fuzzydate)
|
bool Field_time::check_zero_in_date_with_warn(date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
if (!(fuzzydate & TIME_TIME_ONLY) && (fuzzydate & TIME_NO_ZERO_IN_DATE))
|
date_conv_mode_t tmp= date_conv_mode_t(fuzzydate);
|
||||||
|
if (!(tmp & TIME_TIME_ONLY) && (tmp & TIME_NO_ZERO_IN_DATE))
|
||||||
{
|
{
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
@ -5860,7 +5898,7 @@ bool Field_time::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
|||||||
bool Field_time::send_binary(Protocol *protocol)
|
bool Field_time::send_binary(Protocol *protocol)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
get_date(<ime, TIME_TIME_ONLY);
|
get_date(<ime, Time::Options(TIME_TIME_ONLY, get_thd()));
|
||||||
return protocol->store_time(<ime, decimals());
|
return protocol->store_time(<ime, decimals());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5911,7 +5949,7 @@ int Field_time::store_decimal(const my_decimal *d)
|
|||||||
{
|
{
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
int was_cut;
|
int was_cut;
|
||||||
Time tm(get_thd(), &was_cut, d, Time::Options(), decimals());
|
Time tm(get_thd(), &was_cut, d, Time::Options(get_thd()), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5971,8 +6009,7 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
|
|||||||
if (const_item->field_type() != MYSQL_TYPE_TIME)
|
if (const_item->field_type() != MYSQL_TYPE_TIME)
|
||||||
{
|
{
|
||||||
// Get the value of const_item with conversion from DATETIME to TIME
|
// Get the value of const_item with conversion from DATETIME to TIME
|
||||||
Time tm(get_thd(), const_item,
|
Time tm(get_thd(), const_item, Time::Options_cmp(thd, mode));
|
||||||
Time::Options(Time::comparison_flags_for_get_date(), mode));
|
|
||||||
if (!tm.is_valid_time())
|
if (!tm.is_valid_time())
|
||||||
return NULL;
|
return NULL;
|
||||||
/*
|
/*
|
||||||
@ -5996,10 +6033,6 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
|
|||||||
if (const_item->field_type() != MYSQL_TYPE_TIME ||
|
if (const_item->field_type() != MYSQL_TYPE_TIME ||
|
||||||
const_item->decimals != decimals())
|
const_item->decimals != decimals())
|
||||||
{
|
{
|
||||||
Time tm(get_thd(), const_item,
|
|
||||||
Time::Options(TIME_TIME_ONLY, mode));
|
|
||||||
if (!tm.is_valid_time())
|
|
||||||
return NULL;
|
|
||||||
/*
|
/*
|
||||||
Note, the value returned in "ltime" can have more fractional
|
Note, the value returned in "ltime" can have more fractional
|
||||||
digits that decimals(). The Item_time_literal constructor will
|
digits that decimals(). The Item_time_literal constructor will
|
||||||
@ -6014,6 +6047,10 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
|
|||||||
The optimized WHERE will return with "Impossible WHERE", without
|
The optimized WHERE will return with "Impossible WHERE", without
|
||||||
having to do the full table scan.
|
having to do the full table scan.
|
||||||
*/
|
*/
|
||||||
|
Time tm(thd, const_item, Time::Options(TIME_TIME_ONLY, thd, mode),
|
||||||
|
decimals());
|
||||||
|
if (!tm.is_valid_time())
|
||||||
|
return NULL;
|
||||||
return new (thd->mem_root) Item_time_literal(thd, tm.get_mysql_time(),
|
return new (thd->mem_root) Item_time_literal(thd, tm.get_mysql_time(),
|
||||||
decimals());
|
decimals());
|
||||||
}
|
}
|
||||||
@ -6027,7 +6064,7 @@ longlong Field_time_with_dec::val_int(void)
|
|||||||
{
|
{
|
||||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
get_date(<ime, TIME_TIME_ONLY);
|
get_date(<ime, Time::Options(TIME_TIME_ONLY, get_thd()));
|
||||||
longlong val= TIME_to_ulonglong_time(<ime);
|
longlong val= TIME_to_ulonglong_time(<ime);
|
||||||
return ltime.neg ? -val : val;
|
return ltime.neg ? -val : val;
|
||||||
}
|
}
|
||||||
@ -6036,7 +6073,7 @@ double Field_time_with_dec::val_real(void)
|
|||||||
{
|
{
|
||||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
get_date(<ime, TIME_TIME_ONLY);
|
get_date(<ime, Time::Options(TIME_TIME_ONLY, get_thd()));
|
||||||
return TIME_to_double(<ime);
|
return TIME_to_double(<ime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6268,7 +6305,8 @@ int Field_date_common::store(const char *from, size_t len, CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
MYSQL_TIME_STATUS st;
|
MYSQL_TIME_STATUS st;
|
||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
Datetime dt(&st, from, len, cs, sql_mode_for_dates(get_thd()));
|
THD *thd= get_thd();
|
||||||
|
Datetime dt(thd, &st, from, len, cs, Date::Options(thd), 0);
|
||||||
return store_TIME_with_warning(&dt, &str, st.warnings);
|
return store_TIME_with_warning(&dt, &str, st.warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6276,7 +6314,8 @@ int Field_date_common::store(double nr)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
Datetime dt(&error, nr, sql_mode_for_dates(get_thd()));
|
THD *thd= get_thd();
|
||||||
|
Datetime dt(thd, &error, nr, Date::Options(thd), 0);
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6285,7 +6324,8 @@ int Field_date_common::store(longlong nr, bool unsigned_val)
|
|||||||
int error;
|
int error;
|
||||||
Longlong_hybrid tmp(nr, unsigned_val);
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
ErrConvInteger str(tmp);
|
ErrConvInteger str(tmp);
|
||||||
Datetime dt(&error, tmp, sql_mode_for_dates(get_thd()));
|
THD *thd= get_thd();
|
||||||
|
Datetime dt(thd, &error, tmp, Date::Options(thd));
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6294,7 +6334,7 @@ int Field_date_common::store_time_dec(const MYSQL_TIME *ltime, uint dec)
|
|||||||
int error;
|
int error;
|
||||||
ErrConvTime str(ltime);
|
ErrConvTime str(ltime);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Datetime dt(thd, &error, ltime, sql_mode_for_dates(thd));
|
Datetime dt(thd, &error, ltime, Date::Options(thd), 0);
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6302,7 +6342,8 @@ int Field_date_common::store_decimal(const my_decimal *d)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
Datetime tm(&error, d, sql_mode_for_dates(get_thd()));
|
THD *thd= get_thd();
|
||||||
|
Datetime tm(thd, &error, d, Date::Options(thd), 0);
|
||||||
return store_TIME_with_warning(&tm, &str, error);
|
return store_TIME_with_warning(&tm, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6512,8 +6553,14 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
|
|||||||
case ANY_SUBST:
|
case ANY_SUBST:
|
||||||
if (!is_temporal_type_with_date(const_item->field_type()))
|
if (!is_temporal_type_with_date(const_item->field_type()))
|
||||||
{
|
{
|
||||||
// Get the value of const_item with conversion from TIME to DATETIME
|
/*
|
||||||
Datetime dt(thd, const_item, Datetime::comparison_flags_for_get_date());
|
DATE is compared to DATETIME-alike non-temporal values
|
||||||
|
(such as VARCHAR, DECIMAL) as DATETIME, e.g.:
|
||||||
|
WHERE date_column=20010101235959.0000009
|
||||||
|
So here we convert the constant to DATETIME normally.
|
||||||
|
In case if TIME_ROUND_FRACTIONAL is enabled, nanoseconds will round.
|
||||||
|
*/
|
||||||
|
Datetime dt(thd, const_item, Datetime::Options_cmp(thd));
|
||||||
if (!dt.is_valid_datetime())
|
if (!dt.is_valid_datetime())
|
||||||
return NULL;
|
return NULL;
|
||||||
/*
|
/*
|
||||||
@ -6540,10 +6587,17 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
|
|||||||
case IDENTITY_SUBST:
|
case IDENTITY_SUBST:
|
||||||
if (const_item->field_type() != MYSQL_TYPE_DATE)
|
if (const_item->field_type() != MYSQL_TYPE_DATE)
|
||||||
{
|
{
|
||||||
Date d(thd, const_item, date_mode_t(0));
|
/*
|
||||||
if (!d.is_valid_date())
|
DATE is compared to non-temporal as DATETIME.
|
||||||
|
We need to convert to DATETIME first, taking into account the
|
||||||
|
current session rounding mode (even though this is IDENTITY_SUBSTS!),
|
||||||
|
then convert the result to DATE.
|
||||||
|
*/
|
||||||
|
Datetime dt(thd, const_item, Datetime::Options(TIME_CONV_NONE, thd));
|
||||||
|
if (!dt.is_valid_datetime())
|
||||||
return NULL;
|
return NULL;
|
||||||
return new (thd->mem_root) Item_date_literal(thd, d.get_mysql_time());
|
return new (thd->mem_root)
|
||||||
|
Item_date_literal(thd, Date(&dt).get_mysql_time());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6693,7 +6747,8 @@ int Field_datetime::set_time()
|
|||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= table->in_use;
|
||||||
set_notnull();
|
set_notnull();
|
||||||
store_datetime(Datetime(thd, thd->query_start_timeval(), decimals()));
|
// Here we always truncate (not round), no matter what sql_mode is
|
||||||
|
store_datetime(Datetime(thd, thd->query_start_timeval()).trunc(decimals()));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
sql/field.h
16
sql/field.h
@ -1346,7 +1346,6 @@ public:
|
|||||||
void copy_from_tmp(int offset);
|
void copy_from_tmp(int offset);
|
||||||
uint fill_cache_field(struct st_cache_field *copy);
|
uint fill_cache_field(struct st_cache_field *copy);
|
||||||
virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
||||||
bool get_time(MYSQL_TIME *ltime) { return get_date(ltime, TIME_TIME_ONLY); }
|
|
||||||
virtual TYPELIB *get_typelib() const { return NULL; }
|
virtual TYPELIB *get_typelib() const { return NULL; }
|
||||||
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
|
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
|
||||||
virtual CHARSET_INFO *charset_for_protocol(void) const
|
virtual CHARSET_INFO *charset_for_protocol(void) const
|
||||||
@ -2643,7 +2642,8 @@ public:
|
|||||||
int save_in_field(Field *to)
|
int save_in_field(Field *to)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
if (get_date(<ime, date_mode_t(0)))
|
// For temporal types no truncation needed. Rounding mode is not important.
|
||||||
|
if (get_date(<ime, TIME_CONV_NONE | TIME_FRAC_NONE))
|
||||||
return to->reset();
|
return to->reset();
|
||||||
return to->store_time_dec(<ime, decimals());
|
return to->store_time_dec(<ime, decimals());
|
||||||
}
|
}
|
||||||
@ -2721,7 +2721,6 @@ public:
|
|||||||
|
|
||||||
class Field_timestamp :public Field_temporal {
|
class Field_timestamp :public Field_temporal {
|
||||||
protected:
|
protected:
|
||||||
date_mode_t sql_mode_for_timestamp(THD *thd) const;
|
|
||||||
int store_TIME_with_warning(THD *, const Datetime *,
|
int store_TIME_with_warning(THD *, const Datetime *,
|
||||||
const ErrConv *, int warn);
|
const ErrConv *, int warn);
|
||||||
virtual void store_TIMEVAL(const timeval &tv)
|
virtual void store_TIMEVAL(const timeval &tv)
|
||||||
@ -2771,10 +2770,15 @@ public:
|
|||||||
{
|
{
|
||||||
return get_timestamp(ptr, sec_part);
|
return get_timestamp(ptr, sec_part);
|
||||||
}
|
}
|
||||||
// This is used by storage/perfschema
|
/*
|
||||||
void store_TIME(my_time_t timestamp, ulong sec_part)
|
This method is used by storage/perfschema and
|
||||||
|
Item_func_now_local::save_in_field().
|
||||||
|
*/
|
||||||
|
void store_TIME(my_time_t ts, ulong sec_part)
|
||||||
{
|
{
|
||||||
store_TIMESTAMP(Timestamp(timestamp, sec_part).trunc(decimals()));
|
int warn;
|
||||||
|
time_round_mode_t mode= Datetime::default_round_mode(get_thd());
|
||||||
|
store_TIMESTAMP(Timestamp(ts, sec_part).round(decimals(), mode, &warn));
|
||||||
}
|
}
|
||||||
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
||||||
uchar *pack(uchar *to, const uchar *from,
|
uchar *pack(uchar *to, const uchar *from,
|
||||||
|
@ -438,19 +438,19 @@ void Field::do_field_temporal(Copy_field *copy, date_mode_t fuzzydate)
|
|||||||
|
|
||||||
void Field::do_field_datetime(Copy_field *copy)
|
void Field::do_field_datetime(Copy_field *copy)
|
||||||
{
|
{
|
||||||
return do_field_temporal(copy, date_mode_t(0));
|
return do_field_temporal(copy, Datetime::Options(TIME_CONV_NONE, current_thd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Field::do_field_date(Copy_field *copy)
|
void Field::do_field_date(Copy_field *copy)
|
||||||
{
|
{
|
||||||
return do_field_temporal(copy, date_mode_t(0));
|
return do_field_temporal(copy, Date::Options(TIME_CONV_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Field_time::do_field_time(Copy_field *copy)
|
void Field_time::do_field_time(Copy_field *copy)
|
||||||
{
|
{
|
||||||
return do_field_temporal(copy, TIME_TIME_ONLY);
|
return do_field_temporal(copy, Time::Options(current_thd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1051,7 +1051,10 @@ Type_handler_temporal_result::make_sort_key(uchar *to, Item *item,
|
|||||||
Sort_param *param) const
|
Sort_param *param) const
|
||||||
{
|
{
|
||||||
MYSQL_TIME buf;
|
MYSQL_TIME buf;
|
||||||
if (item->get_date_result(current_thd, &buf, TIME_INVALID_DATES))
|
// This is a temporal type. No nanoseconds. Rounding mode is not important.
|
||||||
|
DBUG_ASSERT(item->cmp_type() == TIME_RESULT);
|
||||||
|
static const Temporal::Options opt(TIME_INVALID_DATES, TIME_FRAC_NONE);
|
||||||
|
if (item->get_date_result(current_thd, &buf, opt))
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(item->maybe_null);
|
DBUG_ASSERT(item->maybe_null);
|
||||||
DBUG_ASSERT(item->null_value);
|
DBUG_ASSERT(item->null_value);
|
||||||
|
11
sql/item.cc
11
sql/item.cc
@ -118,12 +118,12 @@ void Item::push_note_converted_to_positive_complement(THD *thd)
|
|||||||
longlong Item::val_datetime_packed_result(THD *thd)
|
longlong Item::val_datetime_packed_result(THD *thd)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime, tmp;
|
MYSQL_TIME ltime, tmp;
|
||||||
if (get_date_result(thd, <ime, Datetime::comparison_flags_for_get_date()))
|
if (get_date_result(thd, <ime, Datetime::Options_cmp(thd)))
|
||||||
return 0;
|
return 0;
|
||||||
if (ltime.time_type != MYSQL_TIMESTAMP_TIME)
|
if (ltime.time_type != MYSQL_TIMESTAMP_TIME)
|
||||||
return pack_time(<ime);
|
return pack_time(<ime);
|
||||||
if ((null_value= time_to_datetime_with_warn(thd, <ime,
|
if ((null_value= time_to_datetime_with_warn(thd, <ime, &tmp,
|
||||||
&tmp, date_mode_t(0))))
|
TIME_CONV_NONE)))
|
||||||
return 0;
|
return 0;
|
||||||
return pack_time(&tmp);
|
return pack_time(&tmp);
|
||||||
}
|
}
|
||||||
@ -305,7 +305,7 @@ int Item::save_date_in_field(Field *field, bool no_conversions)
|
|||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
THD *thd= field->table->in_use;
|
THD *thd= field->table->in_use;
|
||||||
if (get_date(thd, <ime, sql_mode_for_dates(thd)))
|
if (get_date(thd, <ime, Datetime::Options(thd)))
|
||||||
return set_field_to_null_with_conversions(field, no_conversions);
|
return set_field_to_null_with_conversions(field, no_conversions);
|
||||||
field->set_notnull();
|
field->set_notnull();
|
||||||
return field->store_time_dec(<ime, decimals);
|
return field->store_time_dec(<ime, decimals);
|
||||||
@ -9732,7 +9732,8 @@ bool Item_cache_temporal::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzz
|
|||||||
int Item_cache_temporal::save_in_field(Field *field, bool no_conversions)
|
int Item_cache_temporal::save_in_field(Field *field, bool no_conversions)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
if (get_date(field->get_thd(), <ime, date_mode_t(0)))
|
// This is a temporal type. No nanoseconds, so round mode is not important.
|
||||||
|
if (get_date(field->get_thd(), <ime, TIME_CONV_NONE | TIME_FRAC_NONE))
|
||||||
return set_field_to_null_with_conversions(field, no_conversions);
|
return set_field_to_null_with_conversions(field, no_conversions);
|
||||||
field->set_notnull();
|
field->set_notnull();
|
||||||
int error= field->store_time_dec(<ime, decimals);
|
int error= field->store_time_dec(<ime, decimals);
|
||||||
|
20
sql/item.h
20
sql/item.h
@ -1636,28 +1636,28 @@ public:
|
|||||||
bool get_date_from_real(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
bool get_date_from_real(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
||||||
bool get_date_from_string(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
bool get_date_from_string(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
||||||
bool get_time(THD *thd, MYSQL_TIME *ltime)
|
bool get_time(THD *thd, MYSQL_TIME *ltime)
|
||||||
{ return get_date(thd, ltime, Time::flags_for_get_date()); }
|
{ return get_date(thd, ltime, Time::Options(thd)); }
|
||||||
// Get a DATE or DATETIME value in numeric packed format for comparison
|
// Get a DATE or DATETIME value in numeric packed format for comparison
|
||||||
virtual longlong val_datetime_packed(THD *thd)
|
virtual longlong val_datetime_packed(THD *thd)
|
||||||
{
|
{
|
||||||
date_mode_t fuzzydate= Datetime::comparison_flags_for_get_date();
|
return Datetime(thd, this, Datetime::Options_cmp(thd)).to_packed();
|
||||||
return Datetime(current_thd, this, fuzzydate).to_packed();
|
|
||||||
}
|
}
|
||||||
// Get a TIME value in numeric packed format for comparison
|
// Get a TIME value in numeric packed format for comparison
|
||||||
virtual longlong val_time_packed(THD *thd)
|
virtual longlong val_time_packed(THD *thd)
|
||||||
{
|
{
|
||||||
return Time(thd, this, Time::comparison_flags_for_get_date()).to_packed();
|
return Time(thd, this, Time::Options_cmp(thd)).to_packed();
|
||||||
}
|
}
|
||||||
longlong val_datetime_packed_result(THD *thd);
|
longlong val_datetime_packed_result(THD *thd);
|
||||||
longlong val_time_packed_result(THD *thd)
|
longlong val_time_packed_result(THD *thd)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
date_mode_t fuzzydate= Time::comparison_flags_for_get_date();
|
return get_date_result(thd, <ime, Time::Options_cmp(thd)) ? 0 :
|
||||||
return get_date_result(thd, <ime, fuzzydate) ? 0 : pack_time(<ime);
|
pack_time(<ime);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool get_date_result(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
virtual bool get_date_result(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{ return get_date(thd, ltime,fuzzydate); }
|
{ return get_date(thd, ltime,fuzzydate); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The method allows to determine nullness of a complex expression
|
The method allows to determine nullness of a complex expression
|
||||||
without fully evaluating it, instead of calling val/result*() then
|
without fully evaluating it, instead of calling val/result*() then
|
||||||
@ -6441,8 +6441,8 @@ public:
|
|||||||
Item *make_literal(THD *);
|
Item *make_literal(THD *);
|
||||||
longlong val_datetime_packed(THD *thd)
|
longlong val_datetime_packed(THD *thd)
|
||||||
{
|
{
|
||||||
date_mode_t fuzzy= Datetime::comparison_flags_for_get_date();
|
Datetime::Options_cmp opt(thd);
|
||||||
return has_value() ? Datetime(thd, this, fuzzy).to_packed() : 0;
|
return has_value() ? Datetime(thd, this, opt).to_packed() : 0;
|
||||||
}
|
}
|
||||||
longlong val_time_packed(THD *thd)
|
longlong val_time_packed(THD *thd)
|
||||||
{
|
{
|
||||||
@ -6481,7 +6481,7 @@ public:
|
|||||||
}
|
}
|
||||||
longlong val_time_packed(THD *thd)
|
longlong val_time_packed(THD *thd)
|
||||||
{
|
{
|
||||||
return Time(thd, this, Time::comparison_flags_for_get_date()).to_packed();
|
return Time(thd, this, Time::Options_cmp(thd)).to_packed();
|
||||||
}
|
}
|
||||||
longlong val_int()
|
longlong val_int()
|
||||||
{
|
{
|
||||||
@ -6516,7 +6516,7 @@ public:
|
|||||||
}
|
}
|
||||||
longlong val_time_packed(THD *thd)
|
longlong val_time_packed(THD *thd)
|
||||||
{
|
{
|
||||||
return Time(thd, this, Time::comparison_flags_for_get_date()).to_packed();
|
return Time(thd, this, Time::Options_cmp(thd)).to_packed();
|
||||||
}
|
}
|
||||||
longlong val_int() { return has_value() ? Date(this).to_longlong() : 0; }
|
longlong val_int() { return has_value() ? Date(this).to_longlong() : 0; }
|
||||||
double val_real() { return has_value() ? Date(this).to_double() : 0; }
|
double val_real() { return has_value() ? Date(this).to_double() : 0; }
|
||||||
|
@ -2312,7 +2312,8 @@ bool Item_func_ifnull::date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydat
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
for (uint i= 0; i < 2; i++)
|
for (uint i= 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
Datetime dt(thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
|
Datetime_truncation_not_needed dt(thd, args[i],
|
||||||
|
fuzzydate & ~TIME_FUZZY_DATES);
|
||||||
if (!(dt.copy_to_mysql_time(ltime, mysql_timestamp_type())))
|
if (!(dt.copy_to_mysql_time(ltime, mysql_timestamp_type())))
|
||||||
return (null_value= false);
|
return (null_value= false);
|
||||||
}
|
}
|
||||||
@ -2812,7 +2813,7 @@ Item_func_nullif::date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
if (!compare())
|
if (!compare())
|
||||||
return (null_value= true);
|
return (null_value= true);
|
||||||
Datetime dt(thd, args[2], fuzzydate);
|
Datetime_truncation_not_needed dt(thd, args[2], fuzzydate);
|
||||||
return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
|
return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2987,7 +2988,7 @@ bool Item_func_case::date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
|||||||
Item *item= find_item();
|
Item *item= find_item();
|
||||||
if (!item)
|
if (!item)
|
||||||
return (null_value= true);
|
return (null_value= true);
|
||||||
Datetime dt(thd, item, fuzzydate);
|
Datetime_truncation_not_needed dt(thd, item, fuzzydate);
|
||||||
return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
|
return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3339,7 +3340,8 @@ bool Item_func_coalesce::date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzyd
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
for (uint i= 0; i < arg_count; i++)
|
for (uint i= 0; i < arg_count; i++)
|
||||||
{
|
{
|
||||||
Datetime dt(thd, args[i], fuzzydate & ~TIME_FUZZY_DATES);
|
Datetime_truncation_not_needed dt(thd, args[i],
|
||||||
|
fuzzydate & ~TIME_FUZZY_DATES);
|
||||||
if (!dt.copy_to_mysql_time(ltime, mysql_timestamp_type()))
|
if (!dt.copy_to_mysql_time(ltime, mysql_timestamp_type()))
|
||||||
return (null_value= false);
|
return (null_value= false);
|
||||||
}
|
}
|
||||||
|
@ -1127,7 +1127,7 @@ public:
|
|||||||
|
|
||||||
bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
bool date_op(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
Datetime dt(thd, find_item(), fuzzydate);
|
Datetime_truncation_not_needed dt(thd, find_item(), fuzzydate);
|
||||||
return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
|
return (null_value= dt.copy_to_mysql_time(ltime, mysql_timestamp_type()));
|
||||||
}
|
}
|
||||||
bool time_op(THD *thd, MYSQL_TIME *ltime)
|
bool time_op(THD *thd, MYSQL_TIME *ltime)
|
||||||
|
@ -2610,13 +2610,13 @@ bool Item_func_min_max::get_time_native(THD *thd, MYSQL_TIME *ltime)
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
||||||
Time value(thd, args[0], Time::Options(), decimals);
|
Time value(thd, args[0], Time::Options(thd), decimals);
|
||||||
if (!value.is_valid_time())
|
if (!value.is_valid_time())
|
||||||
return (null_value= true);
|
return (null_value= true);
|
||||||
|
|
||||||
for (uint i= 1; i < arg_count ; i++)
|
for (uint i= 1; i < arg_count ; i++)
|
||||||
{
|
{
|
||||||
Time tmp(thd, args[i], Time::Options(), decimals);
|
Time tmp(thd, args[i], Time::Options(thd), decimals);
|
||||||
if (!tmp.is_valid_time())
|
if (!tmp.is_valid_time())
|
||||||
return (null_value= true);
|
return (null_value= true);
|
||||||
|
|
||||||
|
@ -4544,7 +4544,7 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
|
|||||||
case DYN_COL_DATETIME:
|
case DYN_COL_DATETIME:
|
||||||
case DYN_COL_DATE:
|
case DYN_COL_DATE:
|
||||||
args[valpos]->get_date(thd, &vals[i].x.time_value,
|
args[valpos]->get_date(thd, &vals[i].x.time_value,
|
||||||
sql_mode_for_dates(thd));
|
Datetime::Options(thd));
|
||||||
break;
|
break;
|
||||||
case DYN_COL_TIME:
|
case DYN_COL_TIME:
|
||||||
args[valpos]->get_time(thd, &vals[i].x.time_value);
|
args[valpos]->get_time(thd, &vals[i].x.time_value);
|
||||||
|
@ -131,7 +131,7 @@ static bool extract_date_time(THD *thd, DATE_TIME_FORMAT *format,
|
|||||||
timestamp_type cached_timestamp_type,
|
timestamp_type cached_timestamp_type,
|
||||||
const char **sub_pattern_end,
|
const char **sub_pattern_end,
|
||||||
const char *date_time_type,
|
const char *date_time_type,
|
||||||
date_mode_t fuzzydate)
|
date_conv_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
int weekday= 0, yearday= 0, daypart= 0;
|
int weekday= 0, yearday= 0, daypart= 0;
|
||||||
int week_number= -1;
|
int week_number= -1;
|
||||||
@ -808,8 +808,9 @@ longlong Item_func_period_diff::val_int()
|
|||||||
longlong Item_func_to_days::val_int()
|
longlong Item_func_to_days::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
|
THD *thd= current_thd;
|
||||||
return (null_value= !d.is_valid_date()) ? 0 : d.daynr();
|
Datetime d(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd));
|
||||||
|
return (null_value= !d.is_valid_datetime()) ? 0 : d.daynr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -817,14 +818,15 @@ longlong Item_func_to_seconds::val_int_endpoint(bool left_endp,
|
|||||||
bool *incl_endp)
|
bool *incl_endp)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Datetime dt(current_thd, args[0], TIME_FUZZY_DATES);
|
// val_int_endpoint() is called only if args[0] is a temporal Item_field
|
||||||
|
Datetime_from_temporal dt(current_thd, args[0], TIME_FUZZY_DATES);
|
||||||
if ((null_value= !dt.is_valid_datetime()))
|
if ((null_value= !dt.is_valid_datetime()))
|
||||||
{
|
{
|
||||||
/* got NULL, leave the incl_endp intact */
|
/* got NULL, leave the incl_endp intact */
|
||||||
return LONGLONG_MIN;
|
return LONGLONG_MIN;
|
||||||
}
|
}
|
||||||
/* Set to NULL if invalid date, but keep the value */
|
/* Set to NULL if invalid date, but keep the value */
|
||||||
null_value= dt.check_date(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE);
|
null_value= dt.check_date(TIME_NO_ZEROS);
|
||||||
/*
|
/*
|
||||||
Even if the evaluation return NULL, seconds is useful for pruning
|
Even if the evaluation return NULL, seconds is useful for pruning
|
||||||
*/
|
*/
|
||||||
@ -835,7 +837,11 @@ longlong Item_func_to_seconds::val_int()
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
Datetime dt(thd, args[0], TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
|
/*
|
||||||
|
Unlike val_int_endpoint(), we cannot use Datetime_from_temporal here.
|
||||||
|
The argument can be of a non-temporal data type.
|
||||||
|
*/
|
||||||
|
Datetime dt(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd));
|
||||||
return (null_value= !dt.is_valid_datetime()) ? 0 : dt.to_seconds();
|
return (null_value= !dt.is_valid_datetime()) ? 0 : dt.to_seconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,7 +886,8 @@ enum_monotonicity_info Item_func_to_seconds::get_monotonicity_info() const
|
|||||||
longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
|
longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Datetime dt(current_thd, args[0], date_mode_t(0));
|
// val_int_endpoint() is only called if args[0] is a temporal Item_field
|
||||||
|
Datetime_from_temporal dt(current_thd, args[0], TIME_CONV_NONE);
|
||||||
longlong res;
|
longlong res;
|
||||||
if ((null_value= !dt.is_valid_datetime()))
|
if ((null_value= !dt.is_valid_datetime()))
|
||||||
{
|
{
|
||||||
@ -889,7 +896,7 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
|
|||||||
}
|
}
|
||||||
res= (longlong) dt.daynr();
|
res= (longlong) dt.daynr();
|
||||||
/* Set to NULL if invalid date, but keep the value */
|
/* Set to NULL if invalid date, but keep the value */
|
||||||
null_value= dt.check_date(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE);
|
null_value= dt.check_date(TIME_NO_ZEROS);
|
||||||
if (null_value)
|
if (null_value)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -933,22 +940,25 @@ longlong Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
|
|||||||
longlong Item_func_dayofyear::val_int()
|
longlong Item_func_dayofyear::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE);
|
THD *thd= current_thd;
|
||||||
return (null_value= !d.is_valid_date()) ? 0 : d.dayofyear();
|
Datetime d(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd));
|
||||||
|
return (null_value= !d.is_valid_datetime()) ? 0 : d.dayofyear();
|
||||||
}
|
}
|
||||||
|
|
||||||
longlong Item_func_dayofmonth::val_int()
|
longlong Item_func_dayofmonth::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], date_mode_t(0));
|
THD *thd= current_thd;
|
||||||
return (null_value= !d.is_valid_date()) ? 0 : d.get_mysql_time()->day;
|
Datetime d(thd, args[0], Datetime::Options(TIME_CONV_NONE, thd));
|
||||||
|
return (null_value= !d.is_valid_datetime()) ? 0 : d.get_mysql_time()->day;
|
||||||
}
|
}
|
||||||
|
|
||||||
longlong Item_func_month::val_int()
|
longlong Item_func_month::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], date_mode_t(0));
|
THD *thd= current_thd;
|
||||||
return (null_value= !d.is_valid_date()) ? 0 : d.get_mysql_time()->month;
|
Datetime d(thd, args[0], Datetime::Options(TIME_CONV_NONE, thd));
|
||||||
|
return (null_value= !d.is_valid_datetime()) ? 0 : d.get_mysql_time()->month;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -970,9 +980,9 @@ String* Item_func_monthname::val_str(String* str)
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
const char *month_name;
|
const char *month_name;
|
||||||
uint err;
|
uint err;
|
||||||
Date d(current_thd, args[0], date_mode_t(0));
|
THD *thd= current_thd;
|
||||||
|
Datetime d(thd, args[0], Datetime::Options(TIME_CONV_NONE, thd));
|
||||||
if ((null_value= (!d.is_valid_date() || !d.get_mysql_time()->month)))
|
if ((null_value= (!d.is_valid_datetime() || !d.get_mysql_time()->month)))
|
||||||
return (String *) 0;
|
return (String *) 0;
|
||||||
|
|
||||||
month_name= locale->month_names->type_names[d.get_mysql_time()->month - 1];
|
month_name= locale->month_names->type_names[d.get_mysql_time()->month - 1];
|
||||||
@ -989,21 +999,24 @@ String* Item_func_monthname::val_str(String* str)
|
|||||||
longlong Item_func_quarter::val_int()
|
longlong Item_func_quarter::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], date_mode_t(0));
|
THD *thd= current_thd;
|
||||||
return (null_value= !d.is_valid_date()) ? 0 : d.quarter();
|
Datetime d(thd, args[0], Datetime::Options(TIME_CONV_NONE, thd));
|
||||||
|
return (null_value= !d.is_valid_datetime()) ? 0 : d.quarter();
|
||||||
}
|
}
|
||||||
|
|
||||||
longlong Item_func_hour::val_int()
|
longlong Item_func_hour::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Time tm(current_thd, args[0], Time::Options_for_cast());
|
THD *thd= current_thd;
|
||||||
|
Time tm(thd, args[0], Time::Options_for_cast(thd));
|
||||||
return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->hour;
|
return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->hour;
|
||||||
}
|
}
|
||||||
|
|
||||||
longlong Item_func_minute::val_int()
|
longlong Item_func_minute::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Time tm(current_thd, args[0], Time::Options_for_cast());
|
THD *thd= current_thd;
|
||||||
|
Time tm(thd, args[0], Time::Options_for_cast(thd));
|
||||||
return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->minute;
|
return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->minute;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1013,7 +1026,8 @@ longlong Item_func_minute::val_int()
|
|||||||
longlong Item_func_second::val_int()
|
longlong Item_func_second::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Time tm(current_thd, args[0], Time::Options_for_cast());
|
THD *thd= current_thd;
|
||||||
|
Time tm(thd, args[0], Time::Options_for_cast(thd));
|
||||||
return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->second;
|
return (null_value= !tm.is_valid_time()) ? 0 : tm.get_mysql_time()->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1062,8 +1076,8 @@ longlong Item_func_week::val_int()
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
uint week_format;
|
uint week_format;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
Date d(thd, args[0], TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
|
Datetime d(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd));
|
||||||
if ((null_value= !d.is_valid_date()))
|
if ((null_value= !d.is_valid_datetime()))
|
||||||
return 0;
|
return 0;
|
||||||
if (arg_count > 1)
|
if (arg_count > 1)
|
||||||
week_format= (uint)args[1]->val_int();
|
week_format= (uint)args[1]->val_int();
|
||||||
@ -1076,8 +1090,9 @@ longlong Item_func_week::val_int()
|
|||||||
longlong Item_func_yearweek::val_int()
|
longlong Item_func_yearweek::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
|
THD *thd= current_thd;
|
||||||
return (null_value= !d.is_valid_date()) ? 0 :
|
Datetime d(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd));
|
||||||
|
return (null_value= !d.is_valid_datetime()) ? 0 :
|
||||||
d.yearweek((week_mode((uint) args[1]->val_int()) | WEEK_YEAR));
|
d.yearweek((week_mode((uint) args[1]->val_int()) | WEEK_YEAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1085,8 +1100,9 @@ longlong Item_func_yearweek::val_int()
|
|||||||
longlong Item_func_weekday::val_int()
|
longlong Item_func_weekday::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
|
THD *thd= current_thd;
|
||||||
return ((null_value= !d.is_valid_date())) ? 0 :
|
Datetime d(thd, args[0], Datetime::Options(TIME_NO_ZEROS, thd));
|
||||||
|
return ((null_value= !d.is_valid_datetime())) ? 0 :
|
||||||
calc_weekday(d.daynr(), odbc_type) + MY_TEST(odbc_type);
|
calc_weekday(d.daynr(), odbc_type) + MY_TEST(odbc_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1123,8 +1139,9 @@ String* Item_func_dayname::val_str(String* str)
|
|||||||
longlong Item_func_year::val_int()
|
longlong Item_func_year::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Date d(current_thd, args[0], date_mode_t(0));
|
THD *thd= current_thd;
|
||||||
return (null_value= !d.is_valid_date()) ? 0 : d.get_mysql_time()->year;
|
Datetime d(thd, args[0], Datetime::Options(TIME_CONV_NONE, thd));
|
||||||
|
return (null_value= !d.is_valid_datetime()) ? 0 : d.get_mysql_time()->year;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1155,7 +1172,8 @@ enum_monotonicity_info Item_func_year::get_monotonicity_info() const
|
|||||||
longlong Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp)
|
longlong Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Datetime dt(current_thd, args[0], date_mode_t(0));
|
// val_int_endpoint() is cally only if args[0] is a temporal Item_field
|
||||||
|
Datetime_from_temporal dt(current_thd, args[0], TIME_CONV_NONE);
|
||||||
if ((null_value= !dt.is_valid_datetime()))
|
if ((null_value= !dt.is_valid_datetime()))
|
||||||
{
|
{
|
||||||
/* got NULL, leave the incl_endp intact */
|
/* got NULL, leave the incl_endp intact */
|
||||||
@ -1200,7 +1218,7 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
Datetime dt(thd, args[0], TIME_NO_ZERO_IN_DATE);
|
Datetime dt(thd, args[0], Datetime::Options(TIME_NO_ZERO_IN_DATE, thd));
|
||||||
if ((null_value= !dt.is_valid_datetime()))
|
if ((null_value= !dt.is_valid_datetime()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1264,7 +1282,8 @@ longlong Item_func_unix_timestamp::val_int_endpoint(bool left_endp, bool *incl_e
|
|||||||
longlong Item_func_time_to_sec::int_op()
|
longlong Item_func_time_to_sec::int_op()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Time tm(current_thd, args[0], Time::Options_for_cast());
|
THD *thd= current_thd;
|
||||||
|
Time tm(thd, args[0], Time::Options_for_cast(thd));
|
||||||
return ((null_value= !tm.is_valid_time())) ? 0 : tm.to_seconds();
|
return ((null_value= !tm.is_valid_time())) ? 0 : tm.to_seconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1272,7 +1291,8 @@ longlong Item_func_time_to_sec::int_op()
|
|||||||
my_decimal *Item_func_time_to_sec::decimal_op(my_decimal* buf)
|
my_decimal *Item_func_time_to_sec::decimal_op(my_decimal* buf)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Time tm(current_thd, args[0], Time::Options_for_cast());
|
THD *thd= current_thd;
|
||||||
|
Time tm(thd, args[0], Time::Options_for_cast(thd));
|
||||||
if ((null_value= !tm.is_valid_time()))
|
if ((null_value= !tm.is_valid_time()))
|
||||||
return 0;
|
return 0;
|
||||||
const MYSQL_TIME *ltime= tm.get_mysql_time();
|
const MYSQL_TIME *ltime= tm.get_mysql_time();
|
||||||
@ -1621,9 +1641,8 @@ int Item_func_now_local::save_in_field(Field *field, bool no_conversions)
|
|||||||
{
|
{
|
||||||
THD *thd= field->get_thd();
|
THD *thd= field->get_thd();
|
||||||
my_time_t ts= thd->query_start();
|
my_time_t ts= thd->query_start();
|
||||||
uint dec= MY_MIN(decimals, field->decimals());
|
ulong sec_part= decimals ? thd->query_start_sec_part() : 0;
|
||||||
ulong sec_part= dec ? thd->query_start_sec_part() : 0;
|
sec_part-= my_time_fraction_remainder(sec_part, decimals);
|
||||||
sec_part-= my_time_fraction_remainder(sec_part, dec);
|
|
||||||
field->set_notnull();
|
field->set_notnull();
|
||||||
((Field_timestamp*)field)->store_TIME(ts, sec_part);
|
((Field_timestamp*)field)->store_TIME(ts, sec_part);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1698,9 +1717,10 @@ bool Item_func_sysdate_local::get_date(THD *thd, MYSQL_TIME *res,
|
|||||||
bool Item_func_sec_to_time::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
bool Item_func_sec_to_time::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
VSec6 sec(thd, args[0], "seconds", LONGLONG_MAX);
|
VSec9 sec(thd, args[0], "seconds", LONGLONG_MAX);
|
||||||
if ((null_value= sec.is_null()))
|
if ((null_value= sec.is_null()))
|
||||||
return true;
|
return true;
|
||||||
|
sec.round(decimals, thd->temporal_round_mode());
|
||||||
if (sec.sec_to_time(ltime, decimals) && !sec.truncated())
|
if (sec.sec_to_time(ltime, decimals) && !sec.truncated())
|
||||||
sec.make_truncated_warning(thd, "seconds");
|
sec.make_truncated_warning(thd, "seconds");
|
||||||
return false;
|
return false;
|
||||||
@ -1858,10 +1878,10 @@ String *Item_func_date_format::val_str(String *str)
|
|||||||
uint size;
|
uint size;
|
||||||
const MY_LOCALE *lc= 0;
|
const MY_LOCALE *lc= 0;
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
date_conv_mode_t mode= is_time_format ? TIME_TIME_ONLY : TIME_CONV_NONE;
|
||||||
if ((null_value= args[0]->get_date(current_thd, &l_time,
|
THD *thd= current_thd;
|
||||||
is_time_format ? TIME_TIME_ONLY :
|
if ((null_value= args[0]->get_date(thd, &l_time,
|
||||||
date_mode_t(0))))
|
Temporal::Options(mode, thd))))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!(format = args[1]->val_str(str)) || !format->length())
|
if (!(format = args[1]->val_str(str)) || !format->length())
|
||||||
@ -1918,12 +1938,16 @@ bool Item_func_from_unixtime::get_date(THD *thd, MYSQL_TIME *ltime,
|
|||||||
bzero((char *)ltime, sizeof(*ltime));
|
bzero((char *)ltime, sizeof(*ltime));
|
||||||
ltime->time_type= MYSQL_TIMESTAMP_TIME;
|
ltime->time_type= MYSQL_TIMESTAMP_TIME;
|
||||||
|
|
||||||
VSec6 sec(thd, args[0], "unixtime", TIMESTAMP_MAX_VALUE);
|
VSec9 sec(thd, args[0], "unixtime", TIMESTAMP_MAX_VALUE);
|
||||||
DBUG_ASSERT(sec.sec() <= TIMESTAMP_MAX_VALUE);
|
DBUG_ASSERT(sec.sec() <= TIMESTAMP_MAX_VALUE);
|
||||||
|
|
||||||
if (sec.is_null() || sec.truncated() || sec.neg())
|
if (sec.is_null() || sec.truncated() || sec.neg())
|
||||||
return (null_value= 1);
|
return (null_value= 1);
|
||||||
|
|
||||||
|
sec.round(MY_MIN(decimals, TIME_SECOND_PART_DIGITS), thd->temporal_round_mode());
|
||||||
|
if (sec.sec() > TIMESTAMP_MAX_VALUE)
|
||||||
|
return (null_value= true); // Went out of range after rounding
|
||||||
|
|
||||||
tz->gmt_sec_to_TIME(ltime, (my_time_t) sec.sec());
|
tz->gmt_sec_to_TIME(ltime, (my_time_t) sec.sec());
|
||||||
ltime->second_part= sec.usec();
|
ltime->second_part= sec.usec();
|
||||||
|
|
||||||
@ -1952,7 +1976,8 @@ bool Item_func_convert_tz::get_date(THD *thd, MYSQL_TIME *ltime,
|
|||||||
if ((null_value= (from_tz == 0 || to_tz == 0)))
|
if ((null_value= (from_tz == 0 || to_tz == 0)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Datetime *dt= new(ltime) Datetime(thd, args[0], TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
|
Datetime::Options opt(TIME_NO_ZEROS, thd);
|
||||||
|
Datetime *dt= new(ltime) Datetime(thd, args[0], opt);
|
||||||
if ((null_value= !dt->is_valid_datetime()))
|
if ((null_value= !dt->is_valid_datetime()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -2133,7 +2158,8 @@ uint Extract_source::week(THD *thd) const
|
|||||||
longlong Item_extract::val_int()
|
longlong Item_extract::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Extract_source dt(current_thd, args[0], m_date_mode);
|
THD *thd= current_thd;
|
||||||
|
Extract_source dt(thd, args[0], m_date_mode);
|
||||||
if ((null_value= !dt.is_valid_extract_source()))
|
if ((null_value= !dt.is_valid_extract_source()))
|
||||||
return 0;
|
return 0;
|
||||||
switch (int_type) {
|
switch (int_type) {
|
||||||
@ -2141,7 +2167,7 @@ longlong Item_extract::val_int()
|
|||||||
case INTERVAL_YEAR_MONTH: return dt.year_month();
|
case INTERVAL_YEAR_MONTH: return dt.year_month();
|
||||||
case INTERVAL_QUARTER: return dt.quarter();
|
case INTERVAL_QUARTER: return dt.quarter();
|
||||||
case INTERVAL_MONTH: return dt.month();
|
case INTERVAL_MONTH: return dt.month();
|
||||||
case INTERVAL_WEEK: return dt.week(current_thd);
|
case INTERVAL_WEEK: return dt.week(thd);
|
||||||
case INTERVAL_DAY: return dt.day();
|
case INTERVAL_DAY: return dt.day();
|
||||||
case INTERVAL_DAY_HOUR: return dt.day_hour();
|
case INTERVAL_DAY_HOUR: return dt.day_hour();
|
||||||
case INTERVAL_DAY_MINUTE: return dt.day_minute();
|
case INTERVAL_DAY_MINUTE: return dt.day_minute();
|
||||||
@ -2420,7 +2446,7 @@ void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs)
|
|||||||
|
|
||||||
bool Item_time_typecast::get_date(THD *thd, MYSQL_TIME *to, date_mode_t mode)
|
bool Item_time_typecast::get_date(THD *thd, MYSQL_TIME *to, date_mode_t mode)
|
||||||
{
|
{
|
||||||
Time *tm= new(to) Time(thd, args[0], Time::Options_for_cast(mode),
|
Time *tm= new(to) Time(thd, args[0], Time::Options_for_cast(mode, thd),
|
||||||
MY_MIN(decimals, TIME_SECOND_PART_DIGITS));
|
MY_MIN(decimals, TIME_SECOND_PART_DIGITS));
|
||||||
return (null_value= !tm->is_valid_time());
|
return (null_value= !tm->is_valid_time());
|
||||||
}
|
}
|
||||||
@ -2429,7 +2455,8 @@ bool Item_time_typecast::get_date(THD *thd, MYSQL_TIME *to, date_mode_t mode)
|
|||||||
bool Item_date_typecast::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
bool Item_date_typecast::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
date_mode_t tmp= (fuzzydate | sql_mode_for_dates(thd)) & ~TIME_TIME_ONLY;
|
date_mode_t tmp= (fuzzydate | sql_mode_for_dates(thd)) & ~TIME_TIME_ONLY;
|
||||||
Date *d= new(ltime) Date(thd, args[0], tmp);
|
// Force truncation
|
||||||
|
Date *d= new(ltime) Date(thd, args[0], Date::Options(date_conv_mode_t(tmp)));
|
||||||
return (null_value= !d->is_valid_date());
|
return (null_value= !d->is_valid_date());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2437,7 +2464,9 @@ bool Item_date_typecast::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy
|
|||||||
bool Item_datetime_typecast::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
bool Item_datetime_typecast::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
date_mode_t tmp= (fuzzydate | sql_mode_for_dates(thd)) & ~TIME_TIME_ONLY;
|
date_mode_t tmp= (fuzzydate | sql_mode_for_dates(thd)) & ~TIME_TIME_ONLY;
|
||||||
Datetime *dt= new(ltime) Datetime(thd, args[0], tmp,
|
// Force rounding if the current sql_mode says so
|
||||||
|
Datetime::Options opt(date_conv_mode_t(tmp), thd);
|
||||||
|
Datetime *dt= new(ltime) Datetime(thd, args[0], opt,
|
||||||
MY_MIN(decimals, TIME_SECOND_PART_DIGITS));
|
MY_MIN(decimals, TIME_SECOND_PART_DIGITS));
|
||||||
return (null_value= !dt->is_valid_datetime());
|
return (null_value= !dt->is_valid_datetime());
|
||||||
}
|
}
|
||||||
@ -2558,6 +2587,7 @@ bool Item_func_timediff::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy
|
|||||||
return (null_value= adjust_time_range_with_warn(thd, ltime, decimals));
|
return (null_value= adjust_time_range_with_warn(thd, ltime, decimals));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
MAKETIME(h,m,s) is a time function that calculates a time value
|
MAKETIME(h,m,s) is a time function that calculates a time value
|
||||||
from the total number of hours, minutes, and seconds.
|
from the total number of hours, minutes, and seconds.
|
||||||
@ -2569,7 +2599,7 @@ bool Item_func_maketime::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy
|
|||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Longlong_hybrid hour(args[0]->val_int(), args[0]->unsigned_flag);
|
Longlong_hybrid hour(args[0]->val_int(), args[0]->unsigned_flag);
|
||||||
longlong minute= args[1]->val_int();
|
longlong minute= args[1]->val_int();
|
||||||
VSec6 sec(thd, args[2], "seconds", 59);
|
VSec9 sec(thd, args[2], "seconds", 59);
|
||||||
|
|
||||||
DBUG_ASSERT(sec.sec() <= 59);
|
DBUG_ASSERT(sec.sec() <= 59);
|
||||||
if (args[0]->null_value || args[1]->null_value || sec.is_null() ||
|
if (args[0]->null_value || args[1]->null_value || sec.is_null() ||
|
||||||
@ -2577,7 +2607,8 @@ bool Item_func_maketime::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy
|
|||||||
return (null_value= 1);
|
return (null_value= 1);
|
||||||
|
|
||||||
int warn;
|
int warn;
|
||||||
new(ltime) Time(&warn, hour.neg(), hour.abs(), (uint) minute, sec);
|
new(ltime) Time(&warn, hour.neg(), hour.abs(), (uint) minute, sec,
|
||||||
|
thd->temporal_round_mode(), decimals);
|
||||||
if (warn)
|
if (warn)
|
||||||
{
|
{
|
||||||
// use check_time_range() to set ltime to the max value depending on dec
|
// use check_time_range() to set ltime to the max value depending on dec
|
||||||
@ -2607,7 +2638,8 @@ bool Item_func_maketime::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy
|
|||||||
longlong Item_func_microsecond::val_int()
|
longlong Item_func_microsecond::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
Time tm(current_thd, args[0], Time::Options_for_cast());
|
THD *thd= current_thd;
|
||||||
|
Time tm(thd, args[0], Time::Options_for_cast(thd));
|
||||||
return ((null_value= !tm.is_valid_time())) ?
|
return ((null_value= !tm.is_valid_time())) ?
|
||||||
0 : tm.get_mysql_time()->second_part;
|
0 : tm.get_mysql_time()->second_part;
|
||||||
}
|
}
|
||||||
@ -2621,12 +2653,12 @@ longlong Item_func_timestamp_diff::val_int()
|
|||||||
long months= 0;
|
long months= 0;
|
||||||
int neg= 1;
|
int neg= 1;
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
date_mode_t fuzzydate= TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE;
|
Datetime::Options opt(TIME_NO_ZEROS, thd);
|
||||||
|
|
||||||
null_value= 0;
|
null_value= 0;
|
||||||
|
|
||||||
if (Datetime(thd, args[0], fuzzydate).copy_to_mysql_time(<ime1) ||
|
if (Datetime(thd, args[0], opt).copy_to_mysql_time(<ime1) ||
|
||||||
Datetime(thd, args[1], fuzzydate).copy_to_mysql_time(<ime2))
|
Datetime(thd, args[1], opt).copy_to_mysql_time(<ime2))
|
||||||
goto null_date;
|
goto null_date;
|
||||||
|
|
||||||
if (calc_time_diff(<ime2,<ime1, 1,
|
if (calc_time_diff(<ime2,<ime1, 1,
|
||||||
@ -2935,7 +2967,8 @@ bool Item_func_str_to_date::get_date_common(THD *thd, MYSQL_TIME *ltime,
|
|||||||
date_time_format.format.length= format->length();
|
date_time_format.format.length= format->length();
|
||||||
if (extract_date_time(thd, &date_time_format, val->ptr(), val->length(),
|
if (extract_date_time(thd, &date_time_format, val->ptr(), val->length(),
|
||||||
ltime, tstype, 0, "datetime",
|
ltime, tstype, 0, "datetime",
|
||||||
fuzzydate | sql_mode_for_dates(thd)))
|
date_conv_mode_t(fuzzydate) |
|
||||||
|
sql_mode_for_dates(thd)))
|
||||||
return (null_value=1);
|
return (null_value=1);
|
||||||
return (null_value= 0);
|
return (null_value= 0);
|
||||||
}
|
}
|
||||||
@ -2943,8 +2976,10 @@ bool Item_func_str_to_date::get_date_common(THD *thd, MYSQL_TIME *ltime,
|
|||||||
|
|
||||||
bool Item_func_last_day::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
bool Item_func_last_day::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
Date *d= new(ltime) Date(thd, args[0], fuzzydate & ~TIME_TIME_ONLY);
|
Datetime::Options opt(date_conv_mode_t(fuzzydate & ~TIME_TIME_ONLY),
|
||||||
if ((null_value= (!d->is_valid_date() || ltime->month == 0)))
|
time_round_mode_t(fuzzydate));
|
||||||
|
Datetime *d= new(ltime) Datetime(thd, args[0], opt);
|
||||||
|
if ((null_value= (!d->is_valid_datetime() || ltime->month == 0)))
|
||||||
return true;
|
return true;
|
||||||
uint month_idx= ltime->month-1;
|
uint month_idx= ltime->month-1;
|
||||||
ltime->day= days_in_month[month_idx];
|
ltime->day= days_in_month[month_idx];
|
||||||
|
@ -993,12 +993,12 @@ class Item_extract :public Item_int_func,
|
|||||||
EXTRACT(DAY FROM '-24:00:00') -> -1
|
EXTRACT(DAY FROM '-24:00:00') -> -1
|
||||||
*/
|
*/
|
||||||
set_handler(handler_by_length(max_length= length + 1/*sign*/, 11));
|
set_handler(handler_by_length(max_length= length + 1/*sign*/, 11));
|
||||||
m_date_mode= TIME_INTERVAL_DAY;
|
m_date_mode= Temporal::Options(TIME_INTERVAL_DAY, current_thd);
|
||||||
}
|
}
|
||||||
void set_time_length(uint32 length)
|
void set_time_length(uint32 length)
|
||||||
{
|
{
|
||||||
set_handler(handler_by_length(max_length= length + 1/*sign*/, 11));
|
set_handler(handler_by_length(max_length= length + 1/*sign*/, 11));
|
||||||
m_date_mode= TIME_INTERVAL_hhmmssff;
|
m_date_mode= Temporal::Options(TIME_INTERVAL_hhmmssff, current_thd);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
const interval_type int_type; // keep it public
|
const interval_type int_type; // keep it public
|
||||||
@ -1117,7 +1117,7 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
String *val_str(String *to)
|
String *val_str(String *to)
|
||||||
{
|
{
|
||||||
Interval_DDhhmmssff it(current_thd, args[0]);
|
Interval_DDhhmmssff it(current_thd, args[0], m_fsp);
|
||||||
null_value= !it.is_valid_interval_DDhhmmssff();
|
null_value= !it.is_valid_interval_DDhhmmssff();
|
||||||
return it.to_string(to, m_fsp);
|
return it.to_string(to, m_fsp);
|
||||||
}
|
}
|
||||||
@ -1222,7 +1222,7 @@ public:
|
|||||||
}
|
}
|
||||||
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
Datetime dt(thd, args[0], date_mode_t(0));
|
Datetime dt(thd, args[0], Datetime::Options(TIME_CONV_NONE, thd));
|
||||||
if (!dt.is_valid_datetime())
|
if (!dt.is_valid_datetime())
|
||||||
return null_value= true;
|
return null_value= true;
|
||||||
Interval_DDhhmmssff it(thd, args[1]);
|
Interval_DDhhmmssff it(thd, args[1]);
|
||||||
@ -1461,7 +1461,8 @@ public:
|
|||||||
bool get_date(THD *thd, Item_handled_func *item,
|
bool get_date(THD *thd, Item_handled_func *item,
|
||||||
MYSQL_TIME *to, date_mode_t fuzzy) const
|
MYSQL_TIME *to, date_mode_t fuzzy) const
|
||||||
{
|
{
|
||||||
Datetime dt(thd, item->arguments()[0], date_mode_t(0));
|
Datetime::Options opt(TIME_CONV_NONE, thd);
|
||||||
|
Datetime dt(thd, item->arguments()[0], opt);
|
||||||
if (!dt.is_valid_datetime() ||
|
if (!dt.is_valid_datetime() ||
|
||||||
dt.check_date_with_warn(thd, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
|
dt.check_date_with_warn(thd, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
|
||||||
return (item->null_value= true);
|
return (item->null_value= true);
|
||||||
@ -1489,7 +1490,11 @@ public:
|
|||||||
bool get_date(THD *thd, Item_handled_func *item,
|
bool get_date(THD *thd, Item_handled_func *item,
|
||||||
MYSQL_TIME *to, date_mode_t fuzzy) const
|
MYSQL_TIME *to, date_mode_t fuzzy) const
|
||||||
{
|
{
|
||||||
Date d(thd, item->arguments()[0], date_mode_t(0));
|
/*
|
||||||
|
The first argument is known to be of the DATE data type (not DATETIME).
|
||||||
|
We don't need rounding here.
|
||||||
|
*/
|
||||||
|
Date d(thd, item->arguments()[0], TIME_CONV_NONE);
|
||||||
if (!d.is_valid_date() ||
|
if (!d.is_valid_date() ||
|
||||||
d.check_date_with_warn(thd, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
|
d.check_date_with_warn(thd, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE))
|
||||||
return (item->null_value= true);
|
return (item->null_value= true);
|
||||||
@ -1542,10 +1547,10 @@ public:
|
|||||||
bool get_date(THD *thd, Item_handled_func *item,
|
bool get_date(THD *thd, Item_handled_func *item,
|
||||||
MYSQL_TIME *to, date_mode_t fuzzy) const
|
MYSQL_TIME *to, date_mode_t fuzzy) const
|
||||||
{
|
{
|
||||||
if (item->arguments()[0]->get_date(thd, to, date_mode_t(0)) ||
|
if (item->arguments()[0]->
|
||||||
|
get_date(thd, to, Datetime::Options(TIME_CONV_NONE, thd)) ||
|
||||||
(to->time_type != MYSQL_TIMESTAMP_TIME &&
|
(to->time_type != MYSQL_TIMESTAMP_TIME &&
|
||||||
check_date_with_warn(thd, to, TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE,
|
check_date_with_warn(thd, to, TIME_NO_ZEROS, MYSQL_TIMESTAMP_ERROR)))
|
||||||
MYSQL_TIMESTAMP_ERROR)))
|
|
||||||
return (item->null_value= true);
|
return (item->null_value= true);
|
||||||
return (item->null_value= add(thd, item->arguments()[1],
|
return (item->null_value= add(thd, item->arguments()[1],
|
||||||
int_type(item), sub(item), to));
|
int_type(item), sub(item), to));
|
||||||
@ -1581,7 +1586,8 @@ public:
|
|||||||
MYSQL_TIME *to, date_mode_t fuzzy) const
|
MYSQL_TIME *to, date_mode_t fuzzy) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(item->is_fixed());
|
DBUG_ASSERT(item->is_fixed());
|
||||||
Datetime dt(thd, item->arguments()[0], date_mode_t(0));
|
Datetime::Options opt(TIME_CONV_NONE, thd);
|
||||||
|
Datetime dt(thd, item->arguments()[0], opt);
|
||||||
if (!dt.is_valid_datetime())
|
if (!dt.is_valid_datetime())
|
||||||
return item->null_value= true;
|
return item->null_value= true;
|
||||||
Interval_DDhhmmssff it(thd, item->arguments()[1]);
|
Interval_DDhhmmssff it(thd, item->arguments()[1]);
|
||||||
@ -1650,7 +1656,8 @@ public:
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(item->is_fixed());
|
DBUG_ASSERT(item->is_fixed());
|
||||||
// Detect a proper timestamp type based on the argument values
|
// Detect a proper timestamp type based on the argument values
|
||||||
Temporal_hybrid l_time1(thd, item->arguments()[0], TIME_TIME_ONLY);
|
Temporal_hybrid l_time1(thd, item->arguments()[0],
|
||||||
|
Temporal::Options(TIME_TIME_ONLY, thd));
|
||||||
if (!l_time1.is_valid_temporal())
|
if (!l_time1.is_valid_temporal())
|
||||||
return (item->null_value= true);
|
return (item->null_value= true);
|
||||||
Interval_DDhhmmssff l_time2(thd, item->arguments()[1]);
|
Interval_DDhhmmssff l_time2(thd, item->arguments()[1]);
|
||||||
|
@ -142,7 +142,9 @@ Item_func_trt_id::val_int()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
MYSQL_TIME commit_ts;
|
MYSQL_TIME commit_ts;
|
||||||
if (args[0]->get_date(current_thd, &commit_ts, date_mode_t(0)))
|
THD *thd= current_thd;
|
||||||
|
Datetime::Options opt(TIME_CONV_NONE, thd);
|
||||||
|
if (args[0]->get_date(thd, &commit_ts, opt))
|
||||||
{
|
{
|
||||||
null_value= true;
|
null_value= true;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -268,7 +268,8 @@ int str2my_decimal(uint mask, const char *from, size_t length,
|
|||||||
integer part cannot be larger that 1e18 (otherwise it's an overflow).
|
integer part cannot be larger that 1e18 (otherwise it's an overflow).
|
||||||
fractional part is microseconds.
|
fractional part is microseconds.
|
||||||
*/
|
*/
|
||||||
bool my_decimal2seconds(const my_decimal *d, ulonglong *sec, ulong *microsec)
|
bool my_decimal2seconds(const my_decimal *d, ulonglong *sec,
|
||||||
|
ulong *microsec, ulong *nanosec)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
@ -286,6 +287,7 @@ bool my_decimal2seconds(const my_decimal *d, ulonglong *sec, ulong *microsec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*microsec= d->frac ? static_cast<longlong>(d->buf[pos+1]) / (DIG_BASE/1000000) : 0;
|
*microsec= d->frac ? static_cast<longlong>(d->buf[pos+1]) / (DIG_BASE/1000000) : 0;
|
||||||
|
*nanosec= d->frac ? static_cast<longlong>(d->buf[pos+1]) % (DIG_BASE/1000000) : 0;
|
||||||
|
|
||||||
if (pos > 1)
|
if (pos > 1)
|
||||||
{
|
{
|
||||||
|
@ -362,7 +362,8 @@ inline bool str_set_decimal(const my_decimal *val, String *str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool my_decimal2seconds(const my_decimal *d, ulonglong *sec, ulong *microsec);
|
bool my_decimal2seconds(const my_decimal *d, ulonglong *sec,
|
||||||
|
ulong *microsec, ulong *nanosec);
|
||||||
|
|
||||||
my_decimal *seconds2my_decimal(bool sign, ulonglong sec, ulong microsec,
|
my_decimal *seconds2my_decimal(bool sign, ulonglong sec, ulong microsec,
|
||||||
my_decimal *d);
|
my_decimal *d);
|
||||||
|
@ -200,7 +200,8 @@ TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
|
|||||||
"'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
|
"'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
|
||||||
"'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
|
"'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
|
||||||
"'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH',"
|
"'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH',"
|
||||||
"'EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT')") },
|
"'EMPTY_STRING_IS_NULL','SIMULTANEOUS_ASSIGNMENT',"
|
||||||
|
"'TIME_ROUND_FRACTIONAL')") },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -26,13 +26,15 @@ typedef int64 query_id_t;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
"fuzzydate" with strict data type control.
|
"fuzzydate" with strict data type control.
|
||||||
|
Represents a mixture of *only* data type conversion flags, without rounding.
|
||||||
Please keep "explicit" in constructors and conversion methods.
|
Please keep "explicit" in constructors and conversion methods.
|
||||||
*/
|
*/
|
||||||
class date_mode_t
|
class date_conv_mode_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum value_t
|
enum value_t
|
||||||
{
|
{
|
||||||
|
CONV_NONE= 0U,
|
||||||
/*
|
/*
|
||||||
FUZZY_DATES is used for the result will only be used for comparison
|
FUZZY_DATES is used for the result will only be used for comparison
|
||||||
purposes. Conversion is as relaxed as possible.
|
purposes. Conversion is as relaxed as possible.
|
||||||
@ -41,15 +43,159 @@ public:
|
|||||||
TIME_ONLY= 4U,
|
TIME_ONLY= 4U,
|
||||||
INTERVAL_hhmmssff= 8U,
|
INTERVAL_hhmmssff= 8U,
|
||||||
INTERVAL_DAY= 16U,
|
INTERVAL_DAY= 16U,
|
||||||
|
RANGE0_LAST= INTERVAL_DAY,
|
||||||
NO_ZERO_IN_DATE= (1UL << 23), // MODE_NO_ZERO_IN_DATE
|
NO_ZERO_IN_DATE= (1UL << 23), // MODE_NO_ZERO_IN_DATE
|
||||||
NO_ZERO_DATE= (1UL << 24), // MODE_NO_ZERO_DATE
|
NO_ZERO_DATE= (1UL << 24), // MODE_NO_ZERO_DATE
|
||||||
INVALID_DATES= (1UL << 25) // MODE_INVALID_DATES
|
INVALID_DATES= (1UL << 25) // MODE_INVALID_DATES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
BIT-OR for all known values. Let's have a separate enum for it.
|
||||||
|
- We don't put this value "value_t", to avoid handling it in switch().
|
||||||
|
- We don't put this value as a static const inside the class,
|
||||||
|
because "gdb" would display it every time when we do "print"
|
||||||
|
for a time_round_mode_t value.
|
||||||
|
- We can't put into into a function returning this value, because
|
||||||
|
it's not allowed to use functions in static_assert.
|
||||||
|
*/
|
||||||
|
enum known_values_t
|
||||||
|
{
|
||||||
|
KNOWN_MODES= FUZZY_DATES |
|
||||||
|
TIME_ONLY | INTERVAL_hhmmssff | INTERVAL_DAY |
|
||||||
|
NO_ZERO_IN_DATE | NO_ZERO_DATE | INVALID_DATES
|
||||||
|
};
|
||||||
private:
|
private:
|
||||||
value_t m_mode;
|
value_t m_mode;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
explicit date_conv_mode_t(ulonglong fuzzydate)
|
||||||
|
:m_mode((value_t) fuzzydate)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
// Conversion operators
|
||||||
|
explicit operator ulonglong() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
explicit operator bool() const
|
||||||
|
{
|
||||||
|
return m_mode != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unary operators
|
||||||
|
ulonglong operator~() const
|
||||||
|
{
|
||||||
|
return ~m_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dyadic bitwise operators
|
||||||
|
date_conv_mode_t operator&(const date_conv_mode_t &other) const
|
||||||
|
{
|
||||||
|
return date_conv_mode_t(m_mode & other.m_mode);
|
||||||
|
}
|
||||||
|
date_conv_mode_t operator&(const ulonglong other) const
|
||||||
|
{
|
||||||
|
return date_conv_mode_t(m_mode & other);
|
||||||
|
}
|
||||||
|
|
||||||
|
date_conv_mode_t operator|(const date_conv_mode_t &other) const
|
||||||
|
{
|
||||||
|
return date_conv_mode_t(m_mode | other.m_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dyadic bitwise assignment operators
|
||||||
|
date_conv_mode_t &operator&=(const date_conv_mode_t &other)
|
||||||
|
{
|
||||||
|
m_mode= value_t(m_mode & other.m_mode);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
date_conv_mode_t &operator|=(const date_conv_mode_t &other)
|
||||||
|
{
|
||||||
|
m_mode= value_t(m_mode | other.m_mode);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fractional rounding mode for temporal data types.
|
||||||
|
*/
|
||||||
|
class time_round_mode_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum value_t
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Use FRAC_NONE when the value needs no rounding nor truncation,
|
||||||
|
because it is already known not to haveany fractional digits outside
|
||||||
|
of the requested precision.
|
||||||
|
*/
|
||||||
|
FRAC_NONE= 0,
|
||||||
|
FRAC_TRUNCATE= date_conv_mode_t::RANGE0_LAST << 1, // 32
|
||||||
|
FRAC_ROUND= date_conv_mode_t::RANGE0_LAST << 2 // 64
|
||||||
|
};
|
||||||
|
// BIT-OR for all known values. See comments in time_conv_mode_t.
|
||||||
|
enum known_values_t
|
||||||
|
{
|
||||||
|
KNOWN_MODES= FRAC_TRUNCATE | FRAC_ROUND
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
value_t m_mode;
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
explicit time_round_mode_t(ulonglong mode)
|
||||||
|
:m_mode((value_t) mode)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(mode == FRAC_NONE ||
|
||||||
|
mode == FRAC_TRUNCATE ||
|
||||||
|
mode == FRAC_ROUND);
|
||||||
|
}
|
||||||
|
// Conversion operators
|
||||||
|
explicit operator ulonglong() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
value_t mode() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
// Comparison operators
|
||||||
|
bool operator==(const time_round_mode_t &other)
|
||||||
|
{
|
||||||
|
return m_mode == other.m_mode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
"fuzzydate" with strict data type control.
|
||||||
|
Used as a parameter to get_date() and represents a mixture of:
|
||||||
|
- data type conversion flags
|
||||||
|
- fractional second rounding flags
|
||||||
|
Please keep "explicit" in constructors and conversion methods.
|
||||||
|
*/
|
||||||
|
class date_mode_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum value_t
|
||||||
|
{
|
||||||
|
CONV_NONE= date_conv_mode_t::CONV_NONE, // 0
|
||||||
|
FUZZY_DATES= date_conv_mode_t::FUZZY_DATES, // 1
|
||||||
|
TIME_ONLY= date_conv_mode_t::TIME_ONLY, // 4
|
||||||
|
INTERVAL_hhmmssff= date_conv_mode_t::INTERVAL_hhmmssff, // 8
|
||||||
|
INTERVAL_DAY= date_conv_mode_t::INTERVAL_DAY, // 16
|
||||||
|
FRAC_TRUNCATE= time_round_mode_t::FRAC_TRUNCATE, // 32
|
||||||
|
FRAC_ROUND= time_round_mode_t::FRAC_ROUND, // 64
|
||||||
|
NO_ZERO_IN_DATE= date_conv_mode_t::NO_ZERO_IN_DATE, // (1UL << 23)
|
||||||
|
NO_ZERO_DATE= date_conv_mode_t::NO_ZERO_DATE, // (1UL << 24)
|
||||||
|
INVALID_DATES= date_conv_mode_t::INVALID_DATES, // (1UL << 25)
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
value_t m_mode;
|
||||||
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
explicit date_mode_t(ulonglong fuzzydate)
|
explicit date_mode_t(ulonglong fuzzydate)
|
||||||
:m_mode((value_t) fuzzydate)
|
:m_mode((value_t) fuzzydate)
|
||||||
@ -64,11 +210,22 @@ public:
|
|||||||
{
|
{
|
||||||
return m_mode != 0;
|
return m_mode != 0;
|
||||||
}
|
}
|
||||||
|
explicit operator date_conv_mode_t() const
|
||||||
// Unary operators
|
|
||||||
date_mode_t operator~() const
|
|
||||||
{
|
{
|
||||||
return date_mode_t(~m_mode);
|
return date_conv_mode_t(ulonglong(m_mode) & date_conv_mode_t::KNOWN_MODES);
|
||||||
|
}
|
||||||
|
explicit operator time_round_mode_t() const
|
||||||
|
{
|
||||||
|
return time_round_mode_t(ulonglong(m_mode) & time_round_mode_t::KNOWN_MODES);
|
||||||
|
}
|
||||||
|
// Unary operators
|
||||||
|
ulonglong operator~() const
|
||||||
|
{
|
||||||
|
return ~m_mode;
|
||||||
|
}
|
||||||
|
bool operator!() const
|
||||||
|
{
|
||||||
|
return !m_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dyadic bitwise operators
|
// Dyadic bitwise operators
|
||||||
@ -76,6 +233,10 @@ public:
|
|||||||
{
|
{
|
||||||
return date_mode_t(m_mode & other.m_mode);
|
return date_mode_t(m_mode & other.m_mode);
|
||||||
}
|
}
|
||||||
|
date_mode_t operator&(ulonglong other) const
|
||||||
|
{
|
||||||
|
return date_mode_t(m_mode & other);
|
||||||
|
}
|
||||||
|
|
||||||
date_mode_t operator|(const date_mode_t &other) const
|
date_mode_t operator|(const date_mode_t &other) const
|
||||||
{
|
{
|
||||||
@ -94,22 +255,81 @@ public:
|
|||||||
m_mode= value_t(m_mode | other.m_mode);
|
m_mode= value_t(m_mode | other.m_mode);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
date_mode_t &operator|=(const date_conv_mode_t &other)
|
||||||
|
{
|
||||||
|
m_mode= value_t(m_mode | ulonglong(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const date_mode_t
|
// Bitwise OR out-of-class operators for data type mixtures
|
||||||
TIME_FUZZY_DATES (date_mode_t::value_t::FUZZY_DATES),
|
static inline date_mode_t operator|(const date_mode_t &a,
|
||||||
TIME_TIME_ONLY (date_mode_t::value_t::TIME_ONLY),
|
const date_conv_mode_t &b)
|
||||||
TIME_INTERVAL_hhmmssff (date_mode_t::value_t::INTERVAL_hhmmssff),
|
{
|
||||||
TIME_INTERVAL_DAY (date_mode_t::value_t::INTERVAL_DAY),
|
return date_mode_t(ulonglong(a) | ulonglong(b));
|
||||||
TIME_NO_ZERO_IN_DATE (date_mode_t::value_t::NO_ZERO_IN_DATE),
|
}
|
||||||
TIME_NO_ZERO_DATE (date_mode_t::value_t::NO_ZERO_DATE),
|
|
||||||
TIME_INVALID_DATES (date_mode_t::value_t::INVALID_DATES);
|
static inline date_mode_t operator|(const date_conv_mode_t &a,
|
||||||
|
const time_round_mode_t &b)
|
||||||
|
{
|
||||||
|
return date_mode_t(ulonglong(a) | ulonglong(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline date_mode_t operator|(const date_conv_mode_t &a,
|
||||||
|
const date_mode_t &b)
|
||||||
|
{
|
||||||
|
return date_mode_t(ulonglong(a) | ulonglong(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Bitwise AND out-of-class operators for data type mixtures
|
||||||
|
static inline date_conv_mode_t operator&(const date_mode_t &a,
|
||||||
|
const date_conv_mode_t &b)
|
||||||
|
{
|
||||||
|
return date_conv_mode_t(ulonglong(a) & ulonglong(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline date_conv_mode_t operator&(const date_conv_mode_t &a,
|
||||||
|
const date_mode_t &b)
|
||||||
|
{
|
||||||
|
return date_conv_mode_t(ulonglong(a) & ulonglong(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline date_conv_mode_t operator&(sql_mode_t &a,
|
||||||
|
const date_conv_mode_t &b)
|
||||||
|
{
|
||||||
|
return date_conv_mode_t(a & ulonglong(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const date_conv_mode_t
|
||||||
|
TIME_CONV_NONE (date_conv_mode_t::CONV_NONE),
|
||||||
|
TIME_FUZZY_DATES (date_conv_mode_t::FUZZY_DATES),
|
||||||
|
TIME_TIME_ONLY (date_conv_mode_t::TIME_ONLY),
|
||||||
|
TIME_INTERVAL_hhmmssff (date_conv_mode_t::INTERVAL_hhmmssff),
|
||||||
|
TIME_INTERVAL_DAY (date_conv_mode_t::INTERVAL_DAY),
|
||||||
|
TIME_NO_ZERO_IN_DATE (date_conv_mode_t::NO_ZERO_IN_DATE),
|
||||||
|
TIME_NO_ZERO_DATE (date_conv_mode_t::NO_ZERO_DATE),
|
||||||
|
TIME_INVALID_DATES (date_conv_mode_t::INVALID_DATES);
|
||||||
|
|
||||||
|
// An often used combination
|
||||||
|
static const date_conv_mode_t
|
||||||
|
TIME_NO_ZEROS (date_conv_mode_t::NO_ZERO_DATE|
|
||||||
|
date_conv_mode_t::NO_ZERO_IN_DATE);
|
||||||
|
|
||||||
// Flags understood by str_to_xxx, number_to_xxx, check_date
|
// Flags understood by str_to_xxx, number_to_xxx, check_date
|
||||||
static const date_mode_t
|
static const date_conv_mode_t
|
||||||
TIME_MODE_FOR_XXX_TO_DATE (date_mode_t::NO_ZERO_IN_DATE |
|
TIME_MODE_FOR_XXX_TO_DATE (date_mode_t::NO_ZERO_IN_DATE |
|
||||||
date_mode_t::NO_ZERO_DATE |
|
date_mode_t::NO_ZERO_DATE |
|
||||||
date_mode_t::INVALID_DATES);
|
date_mode_t::INVALID_DATES);
|
||||||
|
|
||||||
|
static const time_round_mode_t
|
||||||
|
TIME_FRAC_NONE (time_round_mode_t::FRAC_NONE),
|
||||||
|
TIME_FRAC_TRUNCATE (time_round_mode_t::FRAC_TRUNCATE),
|
||||||
|
TIME_FRAC_ROUND (time_round_mode_t::FRAC_ROUND);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -158,6 +158,7 @@ enum enum_binlog_row_image {
|
|||||||
#define MODE_PAD_CHAR_TO_FULL_LENGTH (1ULL << 31)
|
#define MODE_PAD_CHAR_TO_FULL_LENGTH (1ULL << 31)
|
||||||
#define MODE_EMPTY_STRING_IS_NULL (1ULL << 32)
|
#define MODE_EMPTY_STRING_IS_NULL (1ULL << 32)
|
||||||
#define MODE_SIMULTANEOUS_ASSIGNMENT (1ULL << 33)
|
#define MODE_SIMULTANEOUS_ASSIGNMENT (1ULL << 33)
|
||||||
|
#define MODE_TIME_ROUND_FRACTIONAL (1ULL << 34)
|
||||||
|
|
||||||
/* Bits for different old style modes */
|
/* Bits for different old style modes */
|
||||||
#define OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE (1 << 0)
|
#define OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE (1 << 0)
|
||||||
@ -3419,6 +3420,11 @@ public:
|
|||||||
{
|
{
|
||||||
return Timeval(query_start(), query_start_sec_part());
|
return Timeval(query_start(), query_start_sec_part());
|
||||||
}
|
}
|
||||||
|
time_round_mode_t temporal_round_mode() const
|
||||||
|
{
|
||||||
|
return variables.sql_mode & MODE_TIME_ROUND_FRACTIONAL ?
|
||||||
|
TIME_FRAC_ROUND : TIME_FRAC_TRUNCATE;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct {
|
struct {
|
||||||
@ -4957,13 +4963,17 @@ my_eof(THD *thd)
|
|||||||
(A)->variables.sql_log_bin_off= 0;}
|
(A)->variables.sql_log_bin_off= 0;}
|
||||||
|
|
||||||
|
|
||||||
inline date_mode_t sql_mode_for_dates(THD *thd)
|
inline date_conv_mode_t sql_mode_for_dates(THD *thd)
|
||||||
{
|
{
|
||||||
|
static_assert((date_conv_mode_t::KNOWN_MODES &
|
||||||
|
time_round_mode_t::KNOWN_MODES) == 0,
|
||||||
|
"date_conv_mode_t and time_round_mode_t must use different "
|
||||||
|
"bit values");
|
||||||
static_assert(MODE_NO_ZERO_DATE == date_mode_t::NO_ZERO_DATE &&
|
static_assert(MODE_NO_ZERO_DATE == date_mode_t::NO_ZERO_DATE &&
|
||||||
MODE_NO_ZERO_IN_DATE == date_mode_t::NO_ZERO_IN_DATE &&
|
MODE_NO_ZERO_IN_DATE == date_mode_t::NO_ZERO_IN_DATE &&
|
||||||
MODE_INVALID_DATES == date_mode_t::INVALID_DATES,
|
MODE_INVALID_DATES == date_mode_t::INVALID_DATES,
|
||||||
"sql_mode_t and date_mode_t values must be equal");
|
"sql_mode_t and date_mode_t values must be equal");
|
||||||
return date_mode_t(thd->variables.sql_mode &
|
return date_conv_mode_t(thd->variables.sql_mode &
|
||||||
(MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE | MODE_INVALID_DATES));
|
(MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE | MODE_INVALID_DATES));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8217,6 +8217,7 @@ static int get_part_iter_for_interval_via_mapping(partition_info *part_info,
|
|||||||
field->type() == MYSQL_TYPE_DATETIME))
|
field->type() == MYSQL_TYPE_DATETIME))
|
||||||
{
|
{
|
||||||
/* Monotonic, but return NULL for dates with zeros in month/day. */
|
/* Monotonic, but return NULL for dates with zeros in month/day. */
|
||||||
|
DBUG_ASSERT(field->cmp_type() == TIME_RESULT); // No rounding/truncation
|
||||||
zero_in_start_date= field->get_date(&start_date, date_mode_t(0));
|
zero_in_start_date= field->get_date(&start_date, date_mode_t(0));
|
||||||
DBUG_PRINT("info", ("zero start %u %04d-%02d-%02d",
|
DBUG_PRINT("info", ("zero start %u %04d-%02d-%02d",
|
||||||
zero_in_start_date, start_date.year,
|
zero_in_start_date, start_date.year,
|
||||||
@ -8241,6 +8242,7 @@ static int get_part_iter_for_interval_via_mapping(partition_info *part_info,
|
|||||||
!part_info->part_expr->null_value)
|
!part_info->part_expr->null_value)
|
||||||
{
|
{
|
||||||
MYSQL_TIME end_date;
|
MYSQL_TIME end_date;
|
||||||
|
DBUG_ASSERT(field->cmp_type() == TIME_RESULT); // No rounding/truncation
|
||||||
bool zero_in_end_date= field->get_date(&end_date, date_mode_t(0));
|
bool zero_in_end_date= field->get_date(&end_date, date_mode_t(0));
|
||||||
/*
|
/*
|
||||||
This is an optimization for TO_DAYS()/TO_SECONDS() to avoid scanning
|
This is an optimization for TO_DAYS()/TO_SECONDS() to avoid scanning
|
||||||
|
@ -289,8 +289,8 @@ ulong convert_month_to_period(ulong month)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
check_date_with_warn(THD *thd, const MYSQL_TIME *ltime, date_mode_t fuzzydate,
|
check_date_with_warn(THD *thd, const MYSQL_TIME *ltime,
|
||||||
timestamp_type ts_type)
|
date_conv_mode_t fuzzydate, timestamp_type ts_type)
|
||||||
{
|
{
|
||||||
int unused;
|
int unused;
|
||||||
if (check_date(ltime, fuzzydate, &unused))
|
if (check_date(ltime, fuzzydate, &unused))
|
||||||
@ -372,34 +372,37 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/* Character set-aware version of ascii_to_datetime_or_date_or_time() */
|
/* Character set-aware version of ascii_to_datetime_or_date_or_time() */
|
||||||
bool Temporal::str_to_datetime_or_date_or_time(MYSQL_TIME_STATUS *st,
|
bool Temporal::str_to_datetime_or_date_or_time(THD *thd, MYSQL_TIME_STATUS *st,
|
||||||
const char *str, size_t length,
|
const char *str, size_t length,
|
||||||
CHARSET_INFO *cs,
|
CHARSET_INFO *cs,
|
||||||
date_mode_t fuzzydate)
|
date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
TemporalAsciiBuffer tmp(str, length, cs);
|
TemporalAsciiBuffer tmp(str, length, cs);
|
||||||
return ascii_to_datetime_or_date_or_time(st, tmp.str, tmp.length, fuzzydate);
|
return ascii_to_datetime_or_date_or_time(st, tmp.str, tmp.length, fuzzydate)||
|
||||||
|
add_nanoseconds(thd, &st->warnings, fuzzydate, st->nanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Character set-aware version of str_to_datetime_or_date() */
|
/* Character set-aware version of str_to_datetime_or_date() */
|
||||||
bool Temporal::str_to_datetime_or_date(MYSQL_TIME_STATUS *status,
|
bool Temporal::str_to_datetime_or_date(THD *thd, MYSQL_TIME_STATUS *status,
|
||||||
const char *str, size_t length,
|
const char *str, size_t length,
|
||||||
CHARSET_INFO *cs,
|
CHARSET_INFO *cs,
|
||||||
date_mode_t flags)
|
date_mode_t flags)
|
||||||
{
|
{
|
||||||
TemporalAsciiBuffer tmp(str, length, cs);
|
TemporalAsciiBuffer tmp(str, length, cs);
|
||||||
return ascii_to_datetime_or_date(status, tmp.str, tmp.length, flags);
|
return ascii_to_datetime_or_date(status, tmp.str, tmp.length, flags) ||
|
||||||
|
add_nanoseconds(thd, &status->warnings, flags, status->nanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Character set-aware version of ascii_to_temporal() */
|
/* Character set-aware version of ascii_to_temporal() */
|
||||||
bool Temporal::str_to_temporal(MYSQL_TIME_STATUS *status,
|
bool Temporal::str_to_temporal(THD *thd, MYSQL_TIME_STATUS *status,
|
||||||
const char *str, size_t length, CHARSET_INFO *cs,
|
const char *str, size_t length, CHARSET_INFO *cs,
|
||||||
date_mode_t flags)
|
date_mode_t flags)
|
||||||
{
|
{
|
||||||
TemporalAsciiBuffer tmp(str, length, cs);
|
TemporalAsciiBuffer tmp(str, length, cs);
|
||||||
return ascii_to_temporal(status, tmp.str, tmp.length, flags);
|
return ascii_to_temporal(status, tmp.str, tmp.length, flags) ||
|
||||||
|
add_nanoseconds(thd, &status->warnings, flags, status->nanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1307,7 +1310,7 @@ time_to_datetime(THD *thd, const MYSQL_TIME *from, MYSQL_TIME *to)
|
|||||||
bool
|
bool
|
||||||
time_to_datetime_with_warn(THD *thd,
|
time_to_datetime_with_warn(THD *thd,
|
||||||
const MYSQL_TIME *from, MYSQL_TIME *to,
|
const MYSQL_TIME *from, MYSQL_TIME *to,
|
||||||
date_mode_t fuzzydate)
|
date_conv_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
int warn= 0;
|
int warn= 0;
|
||||||
DBUG_ASSERT(from->time_type == MYSQL_TIMESTAMP_TIME);
|
DBUG_ASSERT(from->time_type == MYSQL_TIMESTAMP_TIME);
|
||||||
|
@ -57,7 +57,7 @@ bool int_to_datetime_with_warn(THD *thd, const Longlong_hybrid &nr,
|
|||||||
bool time_to_datetime(THD *thd, const MYSQL_TIME *tm, MYSQL_TIME *dt);
|
bool time_to_datetime(THD *thd, const MYSQL_TIME *tm, MYSQL_TIME *dt);
|
||||||
bool time_to_datetime_with_warn(THD *thd,
|
bool time_to_datetime_with_warn(THD *thd,
|
||||||
const MYSQL_TIME *tm, MYSQL_TIME *dt,
|
const MYSQL_TIME *tm, MYSQL_TIME *dt,
|
||||||
date_mode_t fuzzydate);
|
date_conv_mode_t fuzzydate);
|
||||||
|
|
||||||
inline void datetime_to_date(MYSQL_TIME *ltime)
|
inline void datetime_to_date(MYSQL_TIME *ltime)
|
||||||
{
|
{
|
||||||
@ -166,13 +166,20 @@ non_zero_date(const MYSQL_TIME *ltime)
|
|||||||
non_zero_hhmmssuu(ltime));
|
non_zero_hhmmssuu(ltime));
|
||||||
}
|
}
|
||||||
static inline bool
|
static inline bool
|
||||||
check_date(const MYSQL_TIME *ltime, date_mode_t flags, int *was_cut)
|
check_date(const MYSQL_TIME *ltime, date_conv_mode_t flags, int *was_cut)
|
||||||
{
|
{
|
||||||
return check_date(ltime, non_zero_date(ltime),
|
return check_date(ltime, non_zero_date(ltime),
|
||||||
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), was_cut);
|
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), was_cut);
|
||||||
}
|
}
|
||||||
bool check_date_with_warn(THD *thd, const MYSQL_TIME *ltime, date_mode_t fuzzy_date,
|
bool check_date_with_warn(THD *thd, const MYSQL_TIME *ltime,
|
||||||
timestamp_type ts_type);
|
date_conv_mode_t fuzzy_date, timestamp_type ts_type);
|
||||||
|
static inline bool
|
||||||
|
check_date_with_warn(THD *thd, const MYSQL_TIME *ltime,
|
||||||
|
date_mode_t fuzzydate, timestamp_type ts_type)
|
||||||
|
{
|
||||||
|
return check_date_with_warn(thd, ltime, date_conv_mode_t(fuzzydate), ts_type);
|
||||||
|
}
|
||||||
|
|
||||||
bool adjust_time_range_with_warn(THD *thd, MYSQL_TIME *ltime, uint dec);
|
bool adjust_time_range_with_warn(THD *thd, MYSQL_TIME *ltime, uint dec);
|
||||||
|
|
||||||
longlong pack_time(const MYSQL_TIME *my_time);
|
longlong pack_time(const MYSQL_TIME *my_time);
|
||||||
|
280
sql/sql_type.cc
280
sql/sql_type.cc
@ -156,12 +156,24 @@ VDec_op::VDec_op(Item_func_hybrid_field_type *item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
date_mode_t Temporal::sql_mode_for_dates(THD *thd)
|
date_conv_mode_t Temporal::sql_mode_for_dates(THD *thd)
|
||||||
{
|
{
|
||||||
return ::sql_mode_for_dates(thd);
|
return ::sql_mode_for_dates(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
time_round_mode_t Temporal::default_round_mode(THD *thd)
|
||||||
|
{
|
||||||
|
return thd->temporal_round_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
time_round_mode_t Timestamp::default_round_mode(THD *thd)
|
||||||
|
{
|
||||||
|
return thd->temporal_round_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
my_decimal *Temporal::to_decimal(my_decimal *to) const
|
my_decimal *Temporal::to_decimal(my_decimal *to) const
|
||||||
{
|
{
|
||||||
return date2my_decimal(this, to);
|
return date2my_decimal(this, to);
|
||||||
@ -183,8 +195,8 @@ void Temporal::make_from_str(THD *thd, Warn *warn,
|
|||||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||||
ER_YES, ErrConvString(str, length,cs).ptr()););
|
ER_YES, ErrConvString(str, length,cs).ptr()););
|
||||||
|
|
||||||
if (str_to_temporal(warn, str, length, cs, fuzzydate))
|
if (str_to_temporal(thd, warn, str, length, cs, fuzzydate))
|
||||||
make_fuzzy_date(&warn->warnings, fuzzydate);
|
make_fuzzy_date(&warn->warnings, date_conv_mode_t(fuzzydate));
|
||||||
if (warn->warnings)
|
if (warn->warnings)
|
||||||
warn->set_str(str, length, &my_charset_bin);
|
warn->set_str(str, length, &my_charset_bin);
|
||||||
}
|
}
|
||||||
@ -197,14 +209,14 @@ Temporal_hybrid::Temporal_hybrid(THD *thd, Item *item, date_mode_t fuzzydate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Sec6::make_from_decimal(const my_decimal *d)
|
void Sec6::make_from_decimal(const my_decimal *d, ulong *nanoseconds)
|
||||||
{
|
{
|
||||||
m_neg= my_decimal2seconds(d, &m_sec, &m_usec);
|
m_neg= my_decimal2seconds(d, &m_sec, &m_usec, nanoseconds);
|
||||||
m_truncated= (m_sec >= LONGLONG_MAX);
|
m_truncated= (m_sec >= LONGLONG_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Sec6::make_from_double(double nr)
|
void Sec6::make_from_double(double nr, ulong *nanoseconds)
|
||||||
{
|
{
|
||||||
if ((m_neg= nr < 0))
|
if ((m_neg= nr < 0))
|
||||||
nr= -nr;
|
nr= -nr;
|
||||||
@ -216,7 +228,9 @@ void Sec6::make_from_double(double nr)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sec= (ulonglong) nr;
|
m_sec= (ulonglong) nr;
|
||||||
m_usec= (ulong) ((nr - floor(nr)) * 1000000);
|
m_usec= (ulong) ((nr - floor(nr)) * 1000000000);
|
||||||
|
*nanoseconds= m_usec % 1000;
|
||||||
|
m_usec/= 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,8 +249,8 @@ bool Sec6::convert_to_mysql_time(THD *thd, int *warn, MYSQL_TIME *ltime,
|
|||||||
bool rc= fuzzydate & (TIME_INTERVAL_hhmmssff | TIME_INTERVAL_DAY) ?
|
bool rc= fuzzydate & (TIME_INTERVAL_hhmmssff | TIME_INTERVAL_DAY) ?
|
||||||
to_datetime_or_to_interval_hhmmssff(ltime, warn) :
|
to_datetime_or_to_interval_hhmmssff(ltime, warn) :
|
||||||
fuzzydate & TIME_TIME_ONLY ?
|
fuzzydate & TIME_TIME_ONLY ?
|
||||||
to_datetime_or_time(ltime, warn, fuzzydate) :
|
to_datetime_or_time(ltime, warn, date_conv_mode_t(fuzzydate)) :
|
||||||
to_datetime_or_date(ltime, warn, fuzzydate);
|
to_datetime_or_date(ltime, warn, date_conv_mode_t(fuzzydate));
|
||||||
DBUG_ASSERT(*warn || !rc);
|
DBUG_ASSERT(*warn || !rc);
|
||||||
if (truncated())
|
if (truncated())
|
||||||
*warn|= MYSQL_TIME_WARN_TRUNCATED;
|
*warn|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
@ -259,7 +273,7 @@ void Temporal::push_conversion_warnings(THD *thd, bool totally_useless_value, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VSec6::VSec6(THD *thd, Item *item, const char *type_str, ulonglong limit)
|
VSec9::VSec9(THD *thd, Item *item, const char *type_str, ulonglong limit)
|
||||||
{
|
{
|
||||||
if (item->decimals == 0)
|
if (item->decimals == 0)
|
||||||
{ // optimize for an important special case
|
{ // optimize for an important special case
|
||||||
@ -277,7 +291,7 @@ VSec6::VSec6(THD *thd, Item *item, const char *type_str, ulonglong limit)
|
|||||||
else if (item->cmp_type() == REAL_RESULT)
|
else if (item->cmp_type() == REAL_RESULT)
|
||||||
{
|
{
|
||||||
double nr= item->val_real();
|
double nr= item->val_real();
|
||||||
make_from_double(nr);
|
make_from_double(nr, &m_nsec);
|
||||||
m_is_null= item->null_value;
|
m_is_null= item->null_value;
|
||||||
if (!m_is_null && m_sec > limit)
|
if (!m_is_null && m_sec > limit)
|
||||||
{
|
{
|
||||||
@ -293,7 +307,7 @@ VSec6::VSec6(THD *thd, Item *item, const char *type_str, ulonglong limit)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
VDec tmp(item);
|
VDec tmp(item);
|
||||||
(m_is_null= tmp.is_null()) ? reset() : make_from_decimal(tmp.ptr());
|
(m_is_null= tmp.is_null()) ? reset() : make_from_decimal(tmp.ptr(), &m_nsec);
|
||||||
if (!m_is_null && m_sec > limit)
|
if (!m_is_null && m_sec > limit)
|
||||||
{
|
{
|
||||||
m_sec= limit;
|
m_sec= limit;
|
||||||
@ -352,7 +366,8 @@ const LEX_CSTRING Interval_DDhhmmssff::m_type_name=
|
|||||||
|
|
||||||
Interval_DDhhmmssff::Interval_DDhhmmssff(THD *thd, Status *st,
|
Interval_DDhhmmssff::Interval_DDhhmmssff(THD *thd, Status *st,
|
||||||
bool push_warnings,
|
bool push_warnings,
|
||||||
Item *item, ulong max_hour)
|
Item *item, ulong max_hour,
|
||||||
|
time_round_mode_t mode, uint dec)
|
||||||
{
|
{
|
||||||
switch (item->cmp_type()) {
|
switch (item->cmp_type()) {
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
@ -361,7 +376,8 @@ Interval_DDhhmmssff::Interval_DDhhmmssff(THD *thd, Status *st,
|
|||||||
break;
|
break;
|
||||||
case TIME_RESULT:
|
case TIME_RESULT:
|
||||||
{
|
{
|
||||||
if (item->get_date(thd, this, TIME_TIME_ONLY))
|
// Rounding mode is not important here
|
||||||
|
if (item->get_date(thd, this, Options(TIME_TIME_ONLY, TIME_FRAC_NONE)))
|
||||||
time_type= MYSQL_TIMESTAMP_NONE;
|
time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
else if (time_type != MYSQL_TIMESTAMP_TIME)
|
else if (time_type != MYSQL_TIMESTAMP_TIME)
|
||||||
{
|
{
|
||||||
@ -392,6 +408,8 @@ Interval_DDhhmmssff::Interval_DDhhmmssff(THD *thd, Status *st,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (mode == TIME_FRAC_ROUND)
|
||||||
|
time_round_or_set_max(dec, &st->warnings, max_hour, st->nanoseconds);
|
||||||
if (hour > max_hour)
|
if (hour > max_hour)
|
||||||
{
|
{
|
||||||
st->warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
st->warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||||
@ -450,7 +468,8 @@ uint Interval_DDhhmmssff::fsp(THD *thd, Item *item)
|
|||||||
if (!item->const_item() || item->is_expensive())
|
if (!item->const_item() || item->is_expensive())
|
||||||
return TIME_SECOND_PART_DIGITS;
|
return TIME_SECOND_PART_DIGITS;
|
||||||
Status st;
|
Status st;
|
||||||
Interval_DDhhmmssff it(thd, &st, false/*no warnings*/, item, UINT_MAX32);
|
Interval_DDhhmmssff it(thd, &st, false/*no warnings*/, item, UINT_MAX32,
|
||||||
|
TIME_FRAC_TRUNCATE, TIME_SECOND_PART_DIGITS);
|
||||||
return it.is_valid_interval_DDhhmmssff() ? st.precision :
|
return it.is_valid_interval_DDhhmmssff() ? st.precision :
|
||||||
TIME_SECOND_PART_DIGITS;
|
TIME_SECOND_PART_DIGITS;
|
||||||
}
|
}
|
||||||
@ -459,13 +478,101 @@ uint Interval_DDhhmmssff::fsp(THD *thd, Item *item)
|
|||||||
void Time::make_from_item(THD *thd, int *warn, Item *item, const Options opt)
|
void Time::make_from_item(THD *thd, int *warn, Item *item, const Options opt)
|
||||||
{
|
{
|
||||||
*warn= 0;
|
*warn= 0;
|
||||||
if (item->get_date(thd, this, opt.get_date_flags()))
|
if (item->get_date(thd, this, opt))
|
||||||
time_type= MYSQL_TIMESTAMP_NONE;
|
time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
else
|
else
|
||||||
valid_MYSQL_TIME_to_valid_value(thd, warn, opt);
|
valid_MYSQL_TIME_to_valid_value(thd, warn, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint msec_round_add[7]=
|
||||||
|
{
|
||||||
|
500000000,
|
||||||
|
50000000,
|
||||||
|
5000000,
|
||||||
|
500000,
|
||||||
|
50000,
|
||||||
|
5000,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Sec9 & Sec9::round(uint dec)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
||||||
|
if (Sec6::add_nanoseconds(m_nsec + msec_round_add[dec]))
|
||||||
|
m_sec++;
|
||||||
|
m_nsec= 0;
|
||||||
|
Sec6::trunc(dec);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Timestamp::round_or_set_max(uint dec, int *warn)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
||||||
|
if (add_nanoseconds_usec(msec_round_add[dec]) &&
|
||||||
|
tv_sec++ >= TIMESTAMP_MAX_VALUE)
|
||||||
|
{
|
||||||
|
tv_sec= TIMESTAMP_MAX_VALUE;
|
||||||
|
tv_usec= TIME_MAX_SECOND_PART;
|
||||||
|
*warn|= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
|
my_timeval_trunc(this, dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Temporal::add_nanoseconds_with_round(THD *thd, int *warn,
|
||||||
|
date_conv_mode_t mode,
|
||||||
|
ulong nsec)
|
||||||
|
{
|
||||||
|
switch (time_type) {
|
||||||
|
case MYSQL_TIMESTAMP_TIME:
|
||||||
|
{
|
||||||
|
ulong max_hour= (mode & (TIME_INTERVAL_DAY | TIME_INTERVAL_hhmmssff)) ?
|
||||||
|
TIME_MAX_INTERVAL_HOUR : TIME_MAX_HOUR;
|
||||||
|
time_round_or_set_max(6, warn, max_hour, nsec);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case MYSQL_TIMESTAMP_DATETIME:
|
||||||
|
return datetime_round_or_invalidate(thd, 6, warn, nsec);
|
||||||
|
case MYSQL_TIMESTAMP_DATE:
|
||||||
|
return false;
|
||||||
|
case MYSQL_TIMESTAMP_NONE:
|
||||||
|
return false;
|
||||||
|
case MYSQL_TIMESTAMP_ERROR:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Temporal::time_round_or_set_max(uint dec, int *warn,
|
||||||
|
ulong max_hour, ulong nsec)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
||||||
|
if (add_nanoseconds_mmssff(nsec) && ++hour > max_hour)
|
||||||
|
{
|
||||||
|
time_hhmmssff_set_max(max_hour);
|
||||||
|
*warn|= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
|
my_time_trunc(this, dec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Time::round_or_set_max(uint dec, int *warn, ulong nsec)
|
||||||
|
{
|
||||||
|
Temporal::time_round_or_set_max(dec, warn, TIME_MAX_HOUR, nsec);
|
||||||
|
DBUG_ASSERT(is_valid_time_slow());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Time::round_or_set_max(uint dec, int *warn)
|
||||||
|
{
|
||||||
|
round_or_set_max(dec, warn, msec_round_add[dec]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create from a DATETIME by subtracting a given number of days,
|
Create from a DATETIME by subtracting a given number of days,
|
||||||
implementing an optimized version of calc_time_diff().
|
implementing an optimized version of calc_time_diff().
|
||||||
@ -586,9 +693,10 @@ Time::Time(int *warn, bool neg, ulonglong hour, uint minute, const Sec6 &second)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Temporal_with_date::make_from_item(THD *thd, Item *item, date_mode_t flags)
|
void Temporal_with_date::make_from_item(THD *thd, Item *item,
|
||||||
|
date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
flags&= ~TIME_TIME_ONLY;
|
date_conv_mode_t flags= date_conv_mode_t(fuzzydate) & ~TIME_TIME_ONLY;
|
||||||
/*
|
/*
|
||||||
Some TIME type items return error when trying to do get_date()
|
Some TIME type items return error when trying to do get_date()
|
||||||
without TIME_TIME_ONLY set (e.g. Item_field for Field_time).
|
without TIME_TIME_ONLY set (e.g. Item_field for Field_time).
|
||||||
@ -596,10 +704,11 @@ void Temporal_with_date::make_from_item(THD *thd, Item *item, date_mode_t flags)
|
|||||||
In the legacy time->datetime conversion mode we do not add TIME_TIME_ONLY
|
In the legacy time->datetime conversion mode we do not add TIME_TIME_ONLY
|
||||||
and leave it to get_date() to check date.
|
and leave it to get_date() to check date.
|
||||||
*/
|
*/
|
||||||
date_mode_t time_flag= (item->field_type() == MYSQL_TYPE_TIME &&
|
date_conv_mode_t time_flag= (item->field_type() == MYSQL_TYPE_TIME &&
|
||||||
!(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST)) ?
|
!(thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST)) ?
|
||||||
TIME_TIME_ONLY : date_mode_t(0);
|
TIME_TIME_ONLY : TIME_CONV_NONE;
|
||||||
if (item->get_date(thd, this, flags | time_flag))
|
Options opt(flags | time_flag, time_round_mode_t(fuzzydate));
|
||||||
|
if (item->get_date(thd, this, opt))
|
||||||
time_type= MYSQL_TIMESTAMP_NONE;
|
time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
else if (time_type == MYSQL_TIMESTAMP_TIME)
|
else if (time_type == MYSQL_TIMESTAMP_TIME)
|
||||||
{
|
{
|
||||||
@ -612,22 +721,17 @@ void Temporal_with_date::make_from_item(THD *thd, Item *item, date_mode_t flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Temporal_with_date::make_from_item(THD *thd, Item *item)
|
void Temporal_with_date::check_date_or_invalidate(int *warn,
|
||||||
|
date_conv_mode_t flags)
|
||||||
{
|
{
|
||||||
return make_from_item(thd, item, sql_mode_for_dates(thd));
|
if (::check_date(this, pack_time(this) != 0,
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Temporal_with_date::check_date_or_invalidate(int *warn, date_mode_t flags)
|
|
||||||
{
|
|
||||||
if (check_date(this, pack_time(this) != 0,
|
|
||||||
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), warn))
|
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), warn))
|
||||||
time_type= MYSQL_TIMESTAMP_NONE;
|
time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Datetime::make_from_time(THD *thd, int *warn, const MYSQL_TIME *from,
|
void Datetime::make_from_time(THD *thd, int *warn, const MYSQL_TIME *from,
|
||||||
date_mode_t flags)
|
date_conv_mode_t flags)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(from->time_type == MYSQL_TIMESTAMP_TIME);
|
DBUG_ASSERT(from->time_type == MYSQL_TIMESTAMP_TIME);
|
||||||
if (time_to_datetime(thd, from, this))
|
if (time_to_datetime(thd, from, this))
|
||||||
@ -641,7 +745,7 @@ void Datetime::make_from_time(THD *thd, int *warn, const MYSQL_TIME *from,
|
|||||||
|
|
||||||
|
|
||||||
void Datetime::make_from_datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
void Datetime::make_from_datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
||||||
date_mode_t flags)
|
date_conv_mode_t flags)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(from->time_type == MYSQL_TIMESTAMP_DATE ||
|
DBUG_ASSERT(from->time_type == MYSQL_TIMESTAMP_DATE ||
|
||||||
from->time_type == MYSQL_TIMESTAMP_DATETIME);
|
from->time_type == MYSQL_TIMESTAMP_DATETIME);
|
||||||
@ -667,7 +771,7 @@ Datetime::Datetime(THD *thd, const timeval &tv)
|
|||||||
|
|
||||||
|
|
||||||
Datetime::Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
Datetime::Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
||||||
date_mode_t flags)
|
date_conv_mode_t flags)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(bool(flags & TIME_TIME_ONLY) == false);
|
DBUG_ASSERT(bool(flags & TIME_TIME_ONLY) == false);
|
||||||
switch (from->time_type) {
|
switch (from->time_type) {
|
||||||
@ -687,6 +791,82 @@ Datetime::Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Temporal::datetime_add_nanoseconds_or_invalidate(THD *thd, int *warn, ulong nsec)
|
||||||
|
{
|
||||||
|
if (!add_nanoseconds_mmssff(nsec))
|
||||||
|
return false;
|
||||||
|
/*
|
||||||
|
Overflow happened on minutes. Now we need to add 1 hour to the value.
|
||||||
|
Catch a special case for the maximum possible date and hour==23, to
|
||||||
|
truncate '9999-12-31 23:59:59.9999999' (with 7 fractional digits)
|
||||||
|
to '9999-12-31 23:59:59.999999' (with 6 fractional digits),
|
||||||
|
with a warning, instead of returning an error, so this statement:
|
||||||
|
INSERT INTO (datetime_column) VALUES ('9999-12-31 23:59:59.9999999');
|
||||||
|
inserts a value truncated to 6 fractional digits, instead of zero
|
||||||
|
date '0000-00-00 00:00:00.000000'.
|
||||||
|
*/
|
||||||
|
if (year == 9999 && month == 12 && day == 31 && hour == 23)
|
||||||
|
{
|
||||||
|
minute= 59;
|
||||||
|
second= 59;
|
||||||
|
second_part= 999999;
|
||||||
|
*warn= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
INTERVAL interval;
|
||||||
|
memset(&interval, 0, sizeof(interval));
|
||||||
|
interval.hour= 1;
|
||||||
|
/* date_add_interval cannot handle bad dates */
|
||||||
|
if (check_date(TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE, warn) ||
|
||||||
|
date_add_interval(thd, this, INTERVAL_HOUR, interval))
|
||||||
|
{
|
||||||
|
make_from_out_of_range(warn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Temporal::datetime_round_or_invalidate(THD *thd, uint dec, int *warn, ulong nsec)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
||||||
|
if (datetime_add_nanoseconds_or_invalidate(thd, warn, nsec))
|
||||||
|
return true;
|
||||||
|
my_time_trunc(this, dec);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Datetime::round_or_invalidate(THD *thd, uint dec, int *warn)
|
||||||
|
{
|
||||||
|
return round_or_invalidate(thd, dec, warn, msec_round_add[dec]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Datetime_from_temporal::Datetime_from_temporal(THD *thd, Item *temporal,
|
||||||
|
date_conv_mode_t fuzzydate)
|
||||||
|
:Datetime(thd, temporal, Options(fuzzydate, TIME_FRAC_NONE))
|
||||||
|
{
|
||||||
|
// Exact rounding mode does not matter
|
||||||
|
DBUG_ASSERT(temporal->cmp_type() == TIME_RESULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Datetime_truncation_not_needed::Datetime_truncation_not_needed(THD *thd, Item *item,
|
||||||
|
date_conv_mode_t mode)
|
||||||
|
:Datetime(thd, item, Options(mode, TIME_FRAC_NONE))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The called Datetime() constructor only would truncate nanoseconds if they
|
||||||
|
existed (but we know there were no nanoseconds). Here we assert that there
|
||||||
|
are also no microsecond digits outside of the scale specified in "dec".
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(!is_valid_datetime() || fraction_remainder(item->decimals) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
uint Type_std_attributes::count_max_decimals(Item **item, uint nitems)
|
uint Type_std_attributes::count_max_decimals(Item **item, uint nitems)
|
||||||
{
|
{
|
||||||
uint res= 0;
|
uint res= 0;
|
||||||
@ -3151,14 +3331,16 @@ void Type_handler_row::Item_update_null_value(Item *item) const
|
|||||||
void Type_handler_time_common::Item_update_null_value(Item *item) const
|
void Type_handler_time_common::Item_update_null_value(Item *item) const
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
(void) item->get_date(current_thd, <ime, TIME_TIME_ONLY);
|
THD *thd= current_thd;
|
||||||
|
(void) item->get_date(thd, <ime, Time::Options(TIME_TIME_ONLY, thd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Type_handler_temporal_with_date::Item_update_null_value(Item *item) const
|
void Type_handler_temporal_with_date::Item_update_null_value(Item *item) const
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
(void) item->get_date(current_thd, <ime, sql_mode_for_dates(current_thd));
|
THD *thd= current_thd;
|
||||||
|
(void) item->get_date(thd, <ime, Datetime::Options(thd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5013,7 +5195,7 @@ bool Type_handler_temporal_result::
|
|||||||
*/
|
*/
|
||||||
return func->get_date_native(thd, ltime,
|
return func->get_date_native(thd, ltime,
|
||||||
fuzzydate & TIME_TIME_ONLY ?
|
fuzzydate & TIME_TIME_ONLY ?
|
||||||
sql_mode_for_dates(thd) :
|
Datetime::Options(thd) :
|
||||||
fuzzydate);
|
fuzzydate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5847,14 +6029,15 @@ uint Type_handler_string_result::Item_temporal_precision(THD *thd, Item *item,
|
|||||||
String *tmp;
|
String *tmp;
|
||||||
MYSQL_TIME_STATUS status;
|
MYSQL_TIME_STATUS status;
|
||||||
DBUG_ASSERT(item->is_fixed());
|
DBUG_ASSERT(item->is_fixed());
|
||||||
|
// Nanosecond rounding is not needed here, for performance purposes
|
||||||
if ((tmp= item->val_str(&buf)) &&
|
if ((tmp= item->val_str(&buf)) &&
|
||||||
(is_time ?
|
(is_time ?
|
||||||
Time(thd, &status, tmp->ptr(), tmp->length(), tmp->charset(),
|
Time(thd, &status, tmp->ptr(), tmp->length(), tmp->charset(),
|
||||||
Time::Options(TIME_TIME_ONLY,
|
Time::Options(TIME_TIME_ONLY, TIME_FRAC_TRUNCATE,
|
||||||
Time::DATETIME_TO_TIME_YYYYMMDD_TRUNCATE)).
|
Time::DATETIME_TO_TIME_YYYYMMDD_TRUNCATE)).
|
||||||
is_valid_time() :
|
is_valid_time() :
|
||||||
Datetime(&status, tmp->ptr(), tmp->length(), tmp->charset(),
|
Datetime(thd, &status, tmp->ptr(), tmp->length(), tmp->charset(),
|
||||||
TIME_FUZZY_DATES).
|
Datetime::Options(TIME_FUZZY_DATES, TIME_FRAC_TRUNCATE)).
|
||||||
is_valid_datetime()))
|
is_valid_datetime()))
|
||||||
return MY_MIN(status.precision, TIME_SECOND_PART_DIGITS);
|
return MY_MIN(status.precision, TIME_SECOND_PART_DIGITS);
|
||||||
return MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
|
return MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
|
||||||
@ -6104,7 +6287,8 @@ bool Type_handler_temporal_with_date::
|
|||||||
Item_save_in_value(THD *thd, Item *item, st_value *value) const
|
Item_save_in_value(THD *thd, Item *item, st_value *value) const
|
||||||
{
|
{
|
||||||
value->m_type= DYN_COL_DATETIME;
|
value->m_type= DYN_COL_DATETIME;
|
||||||
item->get_date(thd, &value->value.m_time, sql_mode_for_dates(thd));
|
item->get_date(thd, &value->value.m_time,
|
||||||
|
Datetime::Options(thd, TIME_FRAC_NONE));
|
||||||
return check_null(item, value);
|
return check_null(item, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6298,7 +6482,7 @@ bool Type_handler::
|
|||||||
Item_send_datetime(Item *item, Protocol *protocol, st_value *buf) const
|
Item_send_datetime(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
item->get_date(protocol->thd, &buf->value.m_time,
|
item->get_date(protocol->thd, &buf->value.m_time,
|
||||||
sql_mode_for_dates(protocol->thd));
|
Datetime::Options(protocol->thd));
|
||||||
if (!item->null_value)
|
if (!item->null_value)
|
||||||
return protocol->store(&buf->value.m_time, item->decimals);
|
return protocol->store(&buf->value.m_time, item->decimals);
|
||||||
return protocol->store_null();
|
return protocol->store_null();
|
||||||
@ -6309,7 +6493,7 @@ bool Type_handler::
|
|||||||
Item_send_date(Item *item, Protocol *protocol, st_value *buf) const
|
Item_send_date(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
item->get_date(protocol->thd, &buf->value.m_time,
|
item->get_date(protocol->thd, &buf->value.m_time,
|
||||||
sql_mode_for_dates(protocol->thd));
|
Date::Options(protocol->thd));
|
||||||
if (!item->null_value)
|
if (!item->null_value)
|
||||||
return protocol->store_date(&buf->value.m_time);
|
return protocol->store_date(&buf->value.m_time);
|
||||||
return protocol->store_null();
|
return protocol->store_null();
|
||||||
@ -7502,8 +7686,8 @@ int Type_handler_temporal_with_date::stored_field_cmp_to_item(THD *thd,
|
|||||||
Item *item) const
|
Item *item) const
|
||||||
{
|
{
|
||||||
MYSQL_TIME field_time, item_time, item_time2, *item_time_cmp= &item_time;
|
MYSQL_TIME field_time, item_time, item_time2, *item_time_cmp= &item_time;
|
||||||
field->get_date(&field_time, TIME_INVALID_DATES);
|
field->get_date(&field_time, Datetime::Options(TIME_INVALID_DATES, thd));
|
||||||
item->get_date(thd, &item_time, TIME_INVALID_DATES);
|
item->get_date(thd, &item_time, Datetime::Options(TIME_INVALID_DATES, thd));
|
||||||
if (item_time.time_type == MYSQL_TIMESTAMP_TIME &&
|
if (item_time.time_type == MYSQL_TIMESTAMP_TIME &&
|
||||||
time_to_datetime(thd, &item_time, item_time_cmp= &item_time2))
|
time_to_datetime(thd, &item_time, item_time_cmp= &item_time2))
|
||||||
return 1;
|
return 1;
|
||||||
@ -7516,8 +7700,8 @@ int Type_handler_time_common::stored_field_cmp_to_item(THD *thd,
|
|||||||
Item *item) const
|
Item *item) const
|
||||||
{
|
{
|
||||||
MYSQL_TIME field_time, item_time;
|
MYSQL_TIME field_time, item_time;
|
||||||
field->get_time(&field_time);
|
field->get_date(&field_time, Time::Options(thd));
|
||||||
item->get_time(thd, &item_time);
|
item->get_date(thd, &item_time, Time::Options(thd));
|
||||||
return my_time_compare(&field_time, &item_time);
|
return my_time_compare(&field_time, &item_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7612,7 +7796,7 @@ Type_handler_date_common::create_literal_item(THD *thd,
|
|||||||
{
|
{
|
||||||
Temporal::Warn st;
|
Temporal::Warn st;
|
||||||
Item_literal *item= NULL;
|
Item_literal *item= NULL;
|
||||||
Temporal_hybrid tmp(thd, &st, str, length, cs, sql_mode_for_dates(thd));
|
Temporal_hybrid tmp(thd, &st, str, length, cs, Temporal_hybrid::Options(thd));
|
||||||
if (tmp.is_valid_temporal() &&
|
if (tmp.is_valid_temporal() &&
|
||||||
tmp.get_mysql_time()->time_type == MYSQL_TIMESTAMP_DATE &&
|
tmp.get_mysql_time()->time_type == MYSQL_TIMESTAMP_DATE &&
|
||||||
!have_important_literal_warnings(&st))
|
!have_important_literal_warnings(&st))
|
||||||
@ -7632,7 +7816,7 @@ Type_handler_temporal_with_date::create_literal_item(THD *thd,
|
|||||||
{
|
{
|
||||||
Temporal::Warn st;
|
Temporal::Warn st;
|
||||||
Item_literal *item= NULL;
|
Item_literal *item= NULL;
|
||||||
Temporal_hybrid tmp(thd, &st, str, length, cs, sql_mode_for_dates(thd));
|
Temporal_hybrid tmp(thd, &st, str, length, cs, Temporal_hybrid::Options(thd));
|
||||||
if (tmp.is_valid_temporal() &&
|
if (tmp.is_valid_temporal() &&
|
||||||
tmp.get_mysql_time()->time_type == MYSQL_TIMESTAMP_DATETIME &&
|
tmp.get_mysql_time()->time_type == MYSQL_TIMESTAMP_DATETIME &&
|
||||||
!have_important_literal_warnings(&st))
|
!have_important_literal_warnings(&st))
|
||||||
@ -7653,7 +7837,7 @@ Type_handler_time_common::create_literal_item(THD *thd,
|
|||||||
{
|
{
|
||||||
MYSQL_TIME_STATUS st;
|
MYSQL_TIME_STATUS st;
|
||||||
Item_literal *item= NULL;
|
Item_literal *item= NULL;
|
||||||
Time::Options opt(TIME_TIME_ONLY, Time::DATETIME_TO_TIME_DISALLOW);
|
Time::Options opt(TIME_TIME_ONLY, thd, Time::DATETIME_TO_TIME_DISALLOW);
|
||||||
Time tmp(thd, &st, str, length, cs, opt);
|
Time tmp(thd, &st, str, length, cs, opt);
|
||||||
if (tmp.is_valid_time() &&
|
if (tmp.is_valid_time() &&
|
||||||
!have_important_literal_warnings(&st))
|
!have_important_literal_warnings(&st))
|
||||||
|
685
sql/sql_type.h
685
sql/sql_type.h
File diff suppressed because it is too large
Load Diff
@ -3353,6 +3353,7 @@ static const char *sql_mode_names[]=
|
|||||||
"ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO", "TRADITIONAL",
|
"ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO", "TRADITIONAL",
|
||||||
"NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", "NO_ENGINE_SUBSTITUTION",
|
"NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", "NO_ENGINE_SUBSTITUTION",
|
||||||
"PAD_CHAR_TO_FULL_LENGTH", "EMPTY_STRING_IS_NULL", "SIMULTANEOUS_ASSIGNMENT",
|
"PAD_CHAR_TO_FULL_LENGTH", "EMPTY_STRING_IS_NULL", "SIMULTANEOUS_ASSIGNMENT",
|
||||||
|
"TIME_ROUND_FRACTIONAL",
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2659,7 +2659,8 @@ public:
|
|||||||
if (!Sys_var_enum::do_check(thd, var))
|
if (!Sys_var_enum::do_check(thd, var))
|
||||||
return false;
|
return false;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
bool res= var->value->get_date(thd, <ime, date_mode_t(0));
|
Datetime::Options opt(TIME_CONV_NONE, thd);
|
||||||
|
bool res= var->value->get_date(thd, <ime, opt);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
var->save_result.ulonglong_value= SYSTEM_TIME_AS_OF;
|
var->save_result.ulonglong_value= SYSTEM_TIME_AS_OF;
|
||||||
@ -2676,7 +2677,9 @@ private:
|
|||||||
{
|
{
|
||||||
if (var->value)
|
if (var->value)
|
||||||
{
|
{
|
||||||
res= var->value->get_date(current_thd, &out.ltime, date_mode_t(0));
|
THD *thd= current_thd;
|
||||||
|
Datetime::Options opt(TIME_CONV_NONE, thd);
|
||||||
|
res= var->value->get_date(thd, &out.ltime, opt);
|
||||||
}
|
}
|
||||||
else // set DEFAULT from global var
|
else // set DEFAULT from global var
|
||||||
{
|
{
|
||||||
|
@ -10576,7 +10576,7 @@ int ha_mroonga::generic_store_bulk_time(Field *field, grn_obj *buf)
|
|||||||
bool truncated = false;
|
bool truncated = false;
|
||||||
Field_time *time_field = (Field_time *)field;
|
Field_time *time_field = (Field_time *)field;
|
||||||
MYSQL_TIME mysql_time;
|
MYSQL_TIME mysql_time;
|
||||||
time_field->get_time(&mysql_time);
|
time_field->get_date(&mysql_time, Time::Options(current_thd));
|
||||||
mrn::TimeConverter time_converter;
|
mrn::TimeConverter time_converter;
|
||||||
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
||||||
&truncated);
|
&truncated);
|
||||||
@ -10596,7 +10596,7 @@ int ha_mroonga::generic_store_bulk_datetime(Field *field, grn_obj *buf)
|
|||||||
bool truncated = false;
|
bool truncated = false;
|
||||||
Field_datetime *datetime_field = (Field_datetime *)field;
|
Field_datetime *datetime_field = (Field_datetime *)field;
|
||||||
MYSQL_TIME mysql_time;
|
MYSQL_TIME mysql_time;
|
||||||
datetime_field->get_time(&mysql_time);
|
datetime_field->get_date(&mysql_time, Time::Options(current_thd));
|
||||||
mrn::TimeConverter time_converter;
|
mrn::TimeConverter time_converter;
|
||||||
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
||||||
&truncated);
|
&truncated);
|
||||||
@ -10657,7 +10657,7 @@ int ha_mroonga::generic_store_bulk_datetime2(Field *field, grn_obj *buf)
|
|||||||
bool truncated = false;
|
bool truncated = false;
|
||||||
Field_datetimef *datetimef_field = (Field_datetimef *)field;
|
Field_datetimef *datetimef_field = (Field_datetimef *)field;
|
||||||
MYSQL_TIME mysql_time;
|
MYSQL_TIME mysql_time;
|
||||||
datetimef_field->get_time(&mysql_time);
|
datetimef_field->get_date(&mysql_time, Time::Options(current_thd));
|
||||||
mrn::TimeConverter time_converter;
|
mrn::TimeConverter time_converter;
|
||||||
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
||||||
&truncated);
|
&truncated);
|
||||||
@ -10682,7 +10682,7 @@ int ha_mroonga::generic_store_bulk_time2(Field *field, grn_obj *buf)
|
|||||||
int error = 0;
|
int error = 0;
|
||||||
bool truncated = false;
|
bool truncated = false;
|
||||||
MYSQL_TIME mysql_time;
|
MYSQL_TIME mysql_time;
|
||||||
field->get_time(&mysql_time);
|
field->get_date(&mysql_time, Time::Options(current_thd));
|
||||||
mrn::TimeConverter time_converter;
|
mrn::TimeConverter time_converter;
|
||||||
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
long long int time = time_converter.mysql_time_to_grn_time(&mysql_time,
|
||||||
&truncated);
|
&truncated);
|
||||||
@ -10707,7 +10707,7 @@ int ha_mroonga::generic_store_bulk_new_date(Field *field, grn_obj *buf)
|
|||||||
bool truncated = false;
|
bool truncated = false;
|
||||||
Field_newdate *newdate_field = (Field_newdate *)field;
|
Field_newdate *newdate_field = (Field_newdate *)field;
|
||||||
MYSQL_TIME mysql_date;
|
MYSQL_TIME mysql_date;
|
||||||
newdate_field->get_time(&mysql_date);
|
newdate_field->get_date(&mysql_date, Time::Options(current_thd));
|
||||||
mrn::TimeConverter time_converter;
|
mrn::TimeConverter time_converter;
|
||||||
long long int time = time_converter.mysql_time_to_grn_time(&mysql_date,
|
long long int time = time_converter.mysql_time_to_grn_time(&mysql_date,
|
||||||
&truncated);
|
&truncated);
|
||||||
@ -11617,14 +11617,14 @@ int ha_mroonga::storage_encode_key_timestamp(Field *field, const uchar *key,
|
|||||||
} else {
|
} else {
|
||||||
Field_timestamp_hires *timestamp_hires_field =
|
Field_timestamp_hires *timestamp_hires_field =
|
||||||
(Field_timestamp_hires *)field;
|
(Field_timestamp_hires *)field;
|
||||||
uint fuzzy_date = 0;
|
|
||||||
uchar *ptr_backup = field->ptr;
|
uchar *ptr_backup = field->ptr;
|
||||||
uchar *null_ptr_backup = field->null_ptr;
|
uchar *null_ptr_backup = field->null_ptr;
|
||||||
TABLE *table_backup = field->table;
|
TABLE *table_backup = field->table;
|
||||||
field->ptr = (uchar *)key;
|
field->ptr = (uchar *)key;
|
||||||
field->null_ptr = (uchar *)(key - 1);
|
field->null_ptr = (uchar *)(key - 1);
|
||||||
field->table = table;
|
field->table = table;
|
||||||
timestamp_hires_field->get_date(&mysql_time, date_mode_t(fuzzy_date));
|
Temporal::Options opt(TIME_CONV_NONE, current_thd);
|
||||||
|
timestamp_hires_field->get_date(&mysql_time, opt);
|
||||||
field->ptr = ptr_backup;
|
field->ptr = ptr_backup;
|
||||||
field->null_ptr = null_ptr_backup;
|
field->null_ptr = null_ptr_backup;
|
||||||
field->table = table_backup;
|
field->table = table_backup;
|
||||||
@ -11675,12 +11675,12 @@ int ha_mroonga::storage_encode_key_time(Field *field, const uchar *key,
|
|||||||
mysql_time.time_type = MYSQL_TIMESTAMP_TIME;
|
mysql_time.time_type = MYSQL_TIMESTAMP_TIME;
|
||||||
} else {
|
} else {
|
||||||
Field_time_hires *time_hires_field = (Field_time_hires *)field;
|
Field_time_hires *time_hires_field = (Field_time_hires *)field;
|
||||||
uint fuzzy_date = 0;
|
|
||||||
uchar *ptr_backup = field->ptr;
|
uchar *ptr_backup = field->ptr;
|
||||||
uchar *null_ptr_backup = field->null_ptr;
|
uchar *null_ptr_backup = field->null_ptr;
|
||||||
field->ptr = (uchar *)key;
|
field->ptr = (uchar *)key;
|
||||||
field->null_ptr = (uchar *)(key - 1);
|
field->null_ptr = (uchar *)(key - 1);
|
||||||
time_hires_field->get_date(&mysql_time, date_mode_t(fuzzy_date));
|
Temporal::Options opt(TIME_CONV_NONE, current_thd);
|
||||||
|
time_hires_field->get_date(&mysql_time, opt);
|
||||||
field->ptr = ptr_backup;
|
field->ptr = ptr_backup;
|
||||||
field->null_ptr = null_ptr_backup;
|
field->null_ptr = null_ptr_backup;
|
||||||
}
|
}
|
||||||
@ -11749,12 +11749,12 @@ int ha_mroonga::storage_encode_key_datetime(Field *field, const uchar *key,
|
|||||||
if (field->decimals() > 0) {
|
if (field->decimals() > 0) {
|
||||||
Field_datetime_hires *datetime_hires_field = (Field_datetime_hires *)field;
|
Field_datetime_hires *datetime_hires_field = (Field_datetime_hires *)field;
|
||||||
MYSQL_TIME mysql_time;
|
MYSQL_TIME mysql_time;
|
||||||
uint fuzzy_date = 0;
|
|
||||||
uchar *ptr_backup = field->ptr;
|
uchar *ptr_backup = field->ptr;
|
||||||
uchar *null_ptr_backup = field->null_ptr;
|
uchar *null_ptr_backup = field->null_ptr;
|
||||||
field->ptr = (uchar *)key;
|
field->ptr = (uchar *)key;
|
||||||
field->null_ptr = (uchar *)(key - 1);
|
field->null_ptr = (uchar *)(key - 1);
|
||||||
datetime_hires_field->get_date(&mysql_time, date_mode_t(fuzzy_date));
|
Temporal::Options opt(TIME_CONV_NONE, current_thd);
|
||||||
|
datetime_hires_field->get_date(&mysql_time, opt);
|
||||||
field->ptr = ptr_backup;
|
field->ptr = ptr_backup;
|
||||||
field->null_ptr = null_ptr_backup;
|
field->null_ptr = null_ptr_backup;
|
||||||
mrn::TimeConverter time_converter;
|
mrn::TimeConverter time_converter;
|
||||||
|
@ -258,8 +258,11 @@ namespace mrn {
|
|||||||
Item *real_value_item = value_item->real_item();
|
Item *real_value_item = value_item->real_item();
|
||||||
switch (field_item->field->type()) {
|
switch (field_item->field->type()) {
|
||||||
case MYSQL_TYPE_TIME:
|
case MYSQL_TYPE_TIME:
|
||||||
error = real_value_item->get_time(current_thd, mysql_time);
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
error= real_value_item->get_date(thd, mysql_time, Time::Options(thd));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MYSQL_TYPE_YEAR:
|
case MYSQL_TYPE_YEAR:
|
||||||
mysql_time->year = static_cast<int>(value_item->val_int());
|
mysql_time->year = static_cast<int>(value_item->val_int());
|
||||||
mysql_time->month = 1;
|
mysql_time->month = 1;
|
||||||
@ -273,9 +276,13 @@ namespace mrn {
|
|||||||
error = false;
|
error = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error = real_value_item->get_date(current_thd, mysql_time, TIME_FUZZY_DATES);
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
Datetime::Options opt(TIME_FUZZY_DATES, thd);
|
||||||
|
error = real_value_item->get_date(thd, mysql_time, opt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user