Commit 77803703 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-8336 The meaning of NO_ZERO_DATE is not clear for DATETIME.

In some cases NO_ZERO_DATE did not allow datetime values with zero date part
and non-zero time part (e.g. '0000-00-00 10:20:30.123456').
Allowing values of this kind in all known pieces of the code.
parent 8154ef4b
......@@ -893,5 +893,57 @@ DROP TABLE t1;
# End of MDEV-8373 Zero date can be inserted in strict no-zero mode through CREATE TABLE AS SELECT timestamp_field
#
#
# MDEV-8336 The meaning of NO_ZERO_DATE is not clear for DATETIME
#
SET sql_mode='NO_ZERO_DATE';
SELECT TIMESTAMP'0000-00-01 10:20:30';
TIMESTAMP'0000-00-01 10:20:30'
0000-00-01 10:20:30
SELECT TIMESTAMP'0000-00-00 10:20:30';
TIMESTAMP'0000-00-00 10:20:30'
0000-00-00 10:20:30
SELECT TIMESTAMP'0000-00-00 00:00:00.000001';
TIMESTAMP'0000-00-00 00:00:00.000001'
0000-00-00 00:00:00.000001
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('0000-00-00 10:20:30');
SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1;
a LEAST(a,'2001-01-01 10:20:30')
0000-00-00 10:20:30 0000-00-00 10:20:30.000000
DROP TABLE t1;
CREATE TABLE t1 (a DATETIME(6));
INSERT INTO t1 VALUES ('0000-00-00 00:00:00.000001');
SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1;
a LEAST(a,'2001-01-01 10:20:30')
0000-00-00 00:00:00.000001 0000-00-00 00:00:00.000001
DROP TABLE t1;
SELECT STR_TO_DATE('0000-00-00 10:20:30','%Y-%m-%d %h:%i:%s');
STR_TO_DATE('0000-00-00 10:20:30','%Y-%m-%d %h:%i:%s')
0000-00-00 10:20:30
SELECT STR_TO_DATE('0000-00-00 00:00:00.000001','%Y-%m-%d %H:%i:%s.%f');
STR_TO_DATE('0000-00-00 00:00:00.000001','%Y-%m-%d %H:%i:%s.%f')
0000-00-00 00:00:00.000001
SET old_mode=zero_date_time_cast;
SELECT CAST(TIME'10:20:30' AS DATETIME);
CAST(TIME'10:20:30' AS DATETIME)
0000-00-00 10:20:30
SELECT CAST(TIME'00:00:00.000001' AS DATETIME(6));
CAST(TIME'00:00:00.000001' AS DATETIME(6))
0000-00-00 00:00:00.000001
SELECT CAST(CAST('10:20:30' AS TIME) AS DATETIME);
CAST(CAST('10:20:30' AS TIME) AS DATETIME)
0000-00-00 10:20:30
SELECT CAST(CAST('00:00:00.000001' AS TIME(6)) AS DATETIME(6));
CAST(CAST('00:00:00.000001' AS TIME(6)) AS DATETIME(6))
0000-00-00 00:00:00.000001
SELECT CAST(CAST(TIMESTAMP'0000-00-00 10:20:30' AS TIME) AS DATETIME);
CAST(CAST(TIMESTAMP'0000-00-00 10:20:30' AS TIME) AS DATETIME)
0000-00-00 10:20:30
SELECT CAST(CAST(TIMESTAMP'0000-00-00 00:00:00.000001' AS TIME(6)) AS DATETIME(6));
CAST(CAST(TIMESTAMP'0000-00-00 00:00:00.000001' AS TIME(6)) AS DATETIME(6))
0000-00-00 00:00:00.000001
SET old_mode=DEFAULT;
SET sql_mode=DEFAULT;
#
# End of 10.1 tests
#
......@@ -622,6 +622,33 @@ let type=DATETIME;
let defval='0000-00-00 00:00:00';
--source include/type_temporal_zero_default.inc
--echo #
--echo # MDEV-8336 The meaning of NO_ZERO_DATE is not clear for DATETIME
--echo #
SET sql_mode='NO_ZERO_DATE';
SELECT TIMESTAMP'0000-00-01 10:20:30';
SELECT TIMESTAMP'0000-00-00 10:20:30';
SELECT TIMESTAMP'0000-00-00 00:00:00.000001';
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('0000-00-00 10:20:30');
SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a DATETIME(6));
INSERT INTO t1 VALUES ('0000-00-00 00:00:00.000001');
SELECT a, LEAST(a,'2001-01-01 10:20:30') FROM t1;
DROP TABLE t1;
SELECT STR_TO_DATE('0000-00-00 10:20:30','%Y-%m-%d %h:%i:%s');
SELECT STR_TO_DATE('0000-00-00 00:00:00.000001','%Y-%m-%d %H:%i:%s.%f');
SET old_mode=zero_date_time_cast;
SELECT CAST(TIME'10:20:30' AS DATETIME);
SELECT CAST(TIME'00:00:00.000001' AS DATETIME(6));
SELECT CAST(CAST('10:20:30' AS TIME) AS DATETIME);
SELECT CAST(CAST('00:00:00.000001' AS TIME(6)) AS DATETIME(6));
SELECT CAST(CAST(TIMESTAMP'0000-00-00 10:20:30' AS TIME) AS DATETIME);
SELECT CAST(CAST(TIMESTAMP'0000-00-00 00:00:00.000001' AS TIME(6)) AS DATETIME(6));
SET old_mode=DEFAULT;
SET sql_mode=DEFAULT;
--echo #
--echo # End of 10.1 tests
--echo #
......@@ -143,13 +143,24 @@ extern DATE_TIME_FORMAT global_time_format;
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
extern LEX_STRING interval_type_to_name[];
static inline bool
non_zero_date(const MYSQL_TIME *ltime)
non_zero_hhmmssuu(const MYSQL_TIME *ltime)
{
return ltime->hour || ltime->minute || ltime->second || ltime->second_part;
}
static inline bool
non_zero_YYMMDD(const MYSQL_TIME *ltime)
{
return ltime->year || ltime->month || ltime->day;
}
static inline bool
non_zero_date(const MYSQL_TIME *ltime)
{
return non_zero_YYMMDD(ltime) ||
(ltime->time_type == MYSQL_TIMESTAMP_DATETIME &&
non_zero_hhmmssuu(ltime));
}
static inline bool
check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut)
{
return check_date(ltime, non_zero_date(ltime), flags, was_cut);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment