diff --git a/mysql-test/include/equal_fields_propagation_datetime.inc b/mysql-test/include/equal_fields_propagation_datetime.inc new file mode 100644 index 00000000000..97a30a83df6 --- /dev/null +++ b/mysql-test/include/equal_fields_propagation_datetime.inc @@ -0,0 +1,64 @@ + +# Trailing garbage in string literals +--eval CREATE TABLE t1 (a $TYPE); +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a='2001-01-01 00:00:00x'; +SELECT * FROM t1 WHERE LENGTH(a) != 20; +SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=30+RAND() AND a='2001-01-01 00:00:00x'; +DROP TABLE t1; + +# Leading spaces in string literals +--eval CREATE TABLE t1 (a $TYPE); +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=19; +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19+RAND() AND a=' 2001-01-01 00:00:00'; +# This should not propagate +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' garbage '; +DROP TABLE t1; + +# Trailing fractional digits in temporal literals +--eval CREATE TABLE t1 (a $TYPE); +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-01 00:00:00.000000'; +SELECT * FROM t1 WHERE LENGTH(a)=19; +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +DROP TABLE t1; + +# Trailing fractional digits in temporal literals, the same precision +--eval CREATE TABLE t1 (a $TYPE(6)); +INSERT INTO t1 VALUES ('2001-01-01 00:00:00.000000'),('2001-01-01 00:00:01.000000'); +SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-01 00:00:00.000000'; +SELECT * FROM t1 WHERE LENGTH(a)=26; +SELECT * FROM t1 WHERE LENGTH(a)=26 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=26 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +DROP TABLE t1; + +# DATETIME/TIMESTAMP column vs TIME literal +SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30'); +--eval CREATE TABLE t1 (a $TYPE); +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a=TIME'00:00:00'; +SELECT * FROM t1 WHERE LENGTH(a)=19; +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIME'00:00:00'; +DROP TABLE t1; + diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 90d66ba6d98..f14b37ff390 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -513,3 +513,86 @@ DROP TABLE t1; # # End of 10.1 tests # +# +# Start of 10.1 tests +# +# +# MDEV-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +# +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-02'); +SELECT * FROM t1 WHERE a='2001-01-01x'; +a +2001-01-01 +Warnings: +Warning 1292 Truncated incorrect date value: '2001-01-01x' +SELECT * FROM t1 WHERE HEX(a)!='323030312D30312D3031'; +a +2001-01-02 +SELECT * FROM t1 WHERE HEX(a)!='323030312D30312D3031' AND a='2001-01-01x'; +a +Warnings: +Warning 1292 Truncated incorrect date value: '2001-01-01x' +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE HEX(a)!='323030312D30312D3031' AND a='2001-01-01x'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Warning 1292 Truncated incorrect date value: '2001-01-01x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE HEX(a)!=CONCAT('xx',RAND()) AND a='2001-01-01x'; +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: +Warning 1292 Truncated incorrect date value: '2001-01-01x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '2001-01-01x') and ((hex(DATE'2001-01-01')) <> concat('xx',rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-02'); +SELECT * FROM t1 WHERE LENGTH(a)=11; +a +SELECT * FROM t1 WHERE LENGTH(a)=11 AND a=' 2001-01-01'; +a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=11 AND a=' 2001-01-01'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=11+RAND() AND a=' 2001-01-01'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 2001-01-01') and ((length(DATE'2001-01-01')) = (11 + rand()))) +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=11+RAND() AND a=' garbage '; +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: +Warning 1292 Incorrect datetime value: ' garbage ' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' garbage ') and (length(`test`.`t1`.`a`) = (11 + rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +a +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='20010101'; +a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='20010101'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8+RAND() AND a='20010101'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '20010101') and ((length(DATE'2001-01-01')) = (8 + rand()))) +DROP TABLE t1; +# +# End of 10.1 tests +# diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 0c62007d2a0..9b01f3b00ef 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -945,5 +945,145 @@ CAST(CAST(TIMESTAMP'0000-00-00 00:00:00.000001' AS TIME(6)) AS DATETIME(6)) SET old_mode=DEFAULT; SET sql_mode=DEFAULT; # +# MDEV-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +# +CREATE TABLE t1 (a DATETIME);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a='2001-01-01 00:00:00x'; +a +2001-01-01 00:00:00 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +SELECT * FROM t1 WHERE LENGTH(a) != 20; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x'; +a +2001-01-01 00:00:00 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x'; +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: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '2001-01-01 00:00:00x') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=30+RAND() AND a='2001-01-01 00:00:00x'; +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: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '2001-01-01 00:00:00x') and ((length(TIMESTAMP'2001-01-01 00:00:00')) <> (30 + rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=19; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = ' 2001-01-01 00:00:00') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19+RAND() AND a=' 2001-01-01 00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 2001-01-01 00:00:00') and ((length(TIMESTAMP'2001-01-01 00:00:00')) = (19 + rand()))) +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' garbage '; +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: +Warning 1292 Incorrect datetime value: ' garbage ' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' garbage ') and (length(`test`.`t1`.`a`) = (30 + rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00 +SELECT * FROM t1 WHERE LENGTH(a)=19; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') and ((length(TIMESTAMP'2001-01-01 00:00:00')) = (30 + rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME(6));; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00.000000'),('2001-01-01 00:00:01.000000'); +SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00.000000 +SELECT * FROM t1 WHERE LENGTH(a)=26; +a +2001-01-01 00:00:00.000000 +2001-01-01 00:00:01.000000 +SELECT * FROM t1 WHERE LENGTH(a)=26 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00.000000 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=26 AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') and ((length(TIMESTAMP'2001-01-01 00:00:00.000000')) = (40 + rand()))) +DROP TABLE t1; +SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30'); +CREATE TABLE t1 (a DATETIME);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a=TIME'00:00:00'; +a +2001-01-01 00:00:00 +SELECT * FROM t1 WHERE LENGTH(a)=19; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIME'00:00:00') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIME'00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIME'00:00:00') and ((length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand()))) +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index 477703edebb..2a99aedda41 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -393,3 +393,152 @@ SET timestamp=DEFAULT; # # End of 10.0 tests # +# +# Start of 10.1 tests +# +# +# MDEV-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +# +# Trailing garbage in string literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +a +00:00:00 +00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='00:00:00x'; +a +00:00:00 +Warnings: +Warning 1292 Truncated incorrect time value: '00:00:00x' +Warning 1292 Truncated incorrect time value: '00:00:00x' +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='00:00:00x'; +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: +Warning 1292 Truncated incorrect time value: '00:00:00x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '00:00:00x') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='00:00:00x'; +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: +Warning 1292 Truncated incorrect time value: '00:00:00x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '00:00:00x') and ((length(TIME'00:00:00')) = (30 + rand()))) +DROP TABLE t1; +# Trailing fractional digits in string literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +a +00:00:00 +00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='00:00:00.000000'; +a +00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '00:00:00.000000') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '00:00:00.000000') and ((length(TIME'00:00:00')) = (30 + rand()))) +DROP TABLE t1; +# Trailing fractional digits in temporal literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +a +00:00:00 +00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'00:00:00.000000'; +a +00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIME'00:00:00.000000') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIME'00:00:00.000000') and ((length(TIME'00:00:00')) = (30 + rand()))) +DROP TABLE t1; +# Trailing fractional digits in temporal literals, same precision +CREATE TABLE t1 (a TIME(6)); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +a +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'00:00:00.000000'; +a +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'00:00:00.000000'; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIME'00:00:00.000000') and ((length(TIME'00:00:00.000000')) = (30 + rand()))) +DROP TABLE t1; +# Leading spaces in string literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +a +00:00:00 +00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=' 00:00:00'; +a +00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=' 00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = ' 00:00:00') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' 00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 00:00:00') and ((length(TIME'00:00:00')) = (30 + rand()))) +DROP TABLE t1; +# Numeric format in string literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +a +00:00:00 +00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='000000'; +a +00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '000000') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '000000') and ((length(TIME'00:00:00')) = (30 + rand()))) +DROP TABLE t1; +# +# End of 10.1 tests +# diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 482f7abc92d..95e89e22f2b 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -800,5 +800,145 @@ 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-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +# +CREATE TABLE t1 (a TIMESTAMP);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a='2001-01-01 00:00:00x'; +a +2001-01-01 00:00:00 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +SELECT * FROM t1 WHERE LENGTH(a) != 20; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x'; +a +2001-01-01 00:00:00 +Warnings: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a) != 20 AND a='2001-01-01 00:00:00x'; +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: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = '2001-01-01 00:00:00x') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)!=30+RAND() AND a='2001-01-01 00:00:00x'; +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: +Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '2001-01-01 00:00:00x') and ((length(TIMESTAMP'2001-01-01 00:00:00')) <> (30 + rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a TIMESTAMP);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=19; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=' 2001-01-01 00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = ' 2001-01-01 00:00:00') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19+RAND() AND a=' 2001-01-01 00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 2001-01-01 00:00:00') and ((length(TIMESTAMP'2001-01-01 00:00:00')) = (19 + rand()))) +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' garbage '; +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: +Warning 1292 Incorrect datetime value: ' garbage ' +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' garbage ') and (length(`test`.`t1`.`a`) = (30 + rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a TIMESTAMP);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00 +SELECT * FROM t1 WHERE LENGTH(a)=19; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') and ((length(TIMESTAMP'2001-01-01 00:00:00')) = (30 + rand()))) +DROP TABLE t1; +CREATE TABLE t1 (a TIMESTAMP(6));; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00.000000'),('2001-01-01 00:00:01.000000'); +SELECT * FROM t1 WHERE a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00.000000 +SELECT * FROM t1 WHERE LENGTH(a)=26; +a +2001-01-01 00:00:00.000000 +2001-01-01 00:00:01.000000 +SELECT * FROM t1 WHERE LENGTH(a)=26 AND a=TIMESTAMP'2001-01-01 00:00:00.000000'; +a +2001-01-01 00:00:00.000000 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=26 AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIMESTAMP'2001-01-01 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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000') and ((length(TIMESTAMP'2001-01-01 00:00:00.000000')) = (40 + rand()))) +DROP TABLE t1; +SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30'); +CREATE TABLE t1 (a TIMESTAMP);; +INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01'); +SELECT * FROM t1 WHERE a=TIME'00:00:00'; +a +2001-01-01 00:00:00 +SELECT * FROM t1 WHERE LENGTH(a)=19; +a +2001-01-01 00:00:00 +2001-01-01 00:00:01 +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=19 AND a=TIME'00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = TIME'00:00:00') +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIME'00:00:00'; +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 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = TIME'00:00:00') and ((length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand()))) +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index c89b1168427..e67bc47f1d7 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -403,6 +403,55 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a IN ('2001-01-01','2 DROP TABLE t1; +--echo # +--echo # End of 10.1 tests +--echo # + +--echo # +--echo # Start of 10.1 tests +--echo # + +--echo # +--echo # MDEV-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +--echo # +# Trailing garbage in string literals +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-02'); +SELECT * FROM t1 WHERE a='2001-01-01x'; +SELECT * FROM t1 WHERE HEX(a)!='323030312D30312D3031'; +SELECT * FROM t1 WHERE HEX(a)!='323030312D30312D3031' AND a='2001-01-01x'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE HEX(a)!='323030312D30312D3031' AND a='2001-01-01x'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE HEX(a)!=CONCAT('xx',RAND()) AND a='2001-01-01x'; +DROP TABLE t1; + +# Leading spaces in string literals +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-02'); +SELECT * FROM t1 WHERE LENGTH(a)=11; +SELECT * FROM t1 WHERE LENGTH(a)=11 AND a=' 2001-01-01'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=11 AND a=' 2001-01-01'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=11+RAND() AND a=' 2001-01-01'; +# This should not propagate +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=11+RAND() AND a=' garbage '; +DROP TABLE t1; + +# Numeric format in string literals +CREATE TABLE t1 (a DATE); +INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='20010101'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='20010101'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8+RAND() AND a='20010101'; +DROP TABLE t1; + + --echo # --echo # End of 10.1 tests --echo # diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index cd311182921..33e4d3f05fd 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -649,6 +649,12 @@ 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 # MDEV-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +--echo # +--let $TYPE= DATETIME +--source include/equal_fields_propagation_datetime.inc + --echo # --echo # End of 10.1 tests --echo # diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index d36c6af65e8..3403bcbfcaa 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -276,3 +276,82 @@ SET timestamp=DEFAULT; --echo # End of 10.0 tests --echo # +--echo # +--echo # Start of 10.1 tests +--echo # + +--echo # +--echo # MDEV-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +--echo # + +--echo # Trailing garbage in string literals + +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='00:00:00x'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='00:00:00x'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='00:00:00x'; +DROP TABLE t1; + +--echo # Trailing fractional digits in string literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='00:00:00.000000'; +DROP TABLE t1; + +--echo # Trailing fractional digits in temporal literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'00:00:00.000000'; +DROP TABLE t1; + +--echo # Trailing fractional digits in temporal literals, same precision +CREATE TABLE t1 (a TIME(6)); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=TIME'00:00:00.000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'00:00:00.000000'; +DROP TABLE t1; + +--echo # Leading spaces in string literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=' 00:00:00'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a=' 00:00:00'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' 00:00:00'; +DROP TABLE t1; + +--echo # Numeric format in string literals +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('00:00:00'),('00:00:01'); +SELECT * FROM t1 WHERE LENGTH(a)=8; +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=8 AND a='000000'; +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='000000'; +DROP TABLE t1; + + +--echo # +--echo # End of 10.1 tests +--echo # diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 53c0fd79acd..97b95d66077 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -538,6 +538,12 @@ let type=TIMESTAMP; let defval='0000-00-00 00:00:00'; --source include/type_temporal_zero_default.inc +--echo # +--echo # MDEV-8699 Wrong result for SELECT..WHERE HEX(date_column)!='323030312D30312D3031' AND date_column='2001-01-01x' +--echo # +--let $TYPE=TIMESTAMP +--source include/equal_fields_propagation_datetime.inc + --echo # --echo # End of 10.1 tests --echo # diff --git a/sql/field.cc b/sql/field.cc index 5a7ac815c9d..714b9dd1dc7 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5515,6 +5515,32 @@ bool Field_temporal::can_optimize_group_min_max(const Item_bool_func *cond, } +Item *Field_temporal::get_equal_const_item_datetime(THD *thd, const Context &ctx, + Item_field *field_item, + Item *const_item) +{ + switch (ctx.subst_constraint()) { + case IDENTITY_SUBST: + if ((const_item->field_type() != MYSQL_TYPE_DATETIME && + const_item->field_type() != MYSQL_TYPE_TIMESTAMP) || + const_item->decimals != decimals()) + { + MYSQL_TIME ltime; + if (const_item->field_type() == MYSQL_TYPE_TIME ? + const_item->get_date_with_conversion(<ime, 0) : + const_item->get_date(<ime, 0)) + return NULL; + return new (thd->mem_root) Item_datetime_literal(thd, <ime, + decimals()); + } + break; + case ANY_SUBST: + break; + } + return const_item; +} + + /**************************************************************************** ** time type ** In string context: HH:MM:SS @@ -5807,6 +5833,29 @@ int Field_time::store_decimal(const my_decimal *d) return store_TIME_with_warning(<ime, &str, was_cut, have_smth_to_conv); } + +Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, + Item *const_item) +{ + switch (ctx.subst_constraint()) { + case IDENTITY_SUBST: + if (const_item->field_type() != MYSQL_TYPE_TIME || + const_item->decimals != decimals()) + { + MYSQL_TIME ltime; + if (const_item->get_date(<ime, TIME_TIME_ONLY)) + return NULL; + return new (thd->mem_root) Item_time_literal(thd, <ime, decimals()); + } + break; + case ANY_SUBST: + break; + } + return const_item; +} + + uint32 Field_time_hires::pack_length() const { return time_hires_bytes[dec]; @@ -6239,6 +6288,29 @@ void Field_newdate::sql_type(String &res) const } +Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, + Item *const_item) +{ + switch (ctx.subst_constraint()) { + case IDENTITY_SUBST: + if (const_item->field_type() != MYSQL_TYPE_DATE) + { + MYSQL_TIME ltime; + if (const_item->field_type() == MYSQL_TYPE_TIME ? + const_item->get_date_with_conversion(<ime, 0) : + const_item->get_date(<ime, 0)) + return NULL; + return new (thd->mem_root) Item_date_literal(thd, <ime); + } + break; + case ANY_SUBST: + break; + } + return const_item; +} + + /**************************************************************************** ** datetime type ** In string context: YYYY-MM-DD HH:MM:DD diff --git a/sql/field.h b/sql/field.h index b08419ae7cc..1c438c25589 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1788,6 +1788,10 @@ public: class Field_temporal: public Field { +protected: + Item *get_equal_const_item_datetime(THD *thd, const Context &ctx, + Item_field *field_item, + Item *const_item); public: Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, @@ -1933,6 +1937,11 @@ public: return unpack_int32(to, from, from_end); } bool validate_value_in_record(THD *thd, const uchar *record) const; + Item *get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, Item *const_item) + { + return get_equal_const_item_datetime(thd, ctx, field_item, const_item); + } uint size_of() const { return sizeof(*this); } }; @@ -2121,6 +2130,8 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { return Field_newdate::get_TIME(ltime, ptr, fuzzydate); } uint size_of() const { return sizeof(*this); } + Item *get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, Item *const_item); }; @@ -2164,6 +2175,8 @@ public: Field *new_key_field(MEM_ROOT *root, TABLE *new_table, uchar *new_ptr, uint32 length, uchar *new_null_ptr, uint new_null_bit); + Item *get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, Item *const_item); }; @@ -2322,6 +2335,11 @@ public: { return unpack_int64(to, from, from_end); } + Item *get_equal_const_item(THD *thd, const Context &ctx, + Item_field *field_item, Item *const_item) + { + return get_equal_const_item_datetime(thd, ctx, field_item, const_item); + } uint size_of() const { return sizeof(*this); } }; diff --git a/sql/item.cc b/sql/item.cc index b7a0a40714a..1bc75bdbf10 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5366,7 +5366,32 @@ Item *Item_field::propagate_equal_fields(THD *thd, return this; } Item *item= item_equal->get_const(); - return item ? field->get_equal_const_item(thd, ctx, this, item) : this; + if (!item) + { + /* + The found Item_equal is Okey, but it does not have a constant + item yet. Keep this->item_equal point to the found Item_equal. + */ + return this; + } + if (!(item= field->get_equal_const_item(thd, ctx, this, item))) + { + /* + Could not do safe conversion from the original constant item + to a field-compatible constant item. + For example, we tried to optimize: + WHERE date_column=' garbage ' AND LENGTH(date_column)=8; + to + WHERE date_column=' garbage ' AND LENGTH(DATE'XXXX-YY-ZZ'); + but failed to create a valid DATE literal from the given string literal. + + Do not do constant propagation in such cases and unlink + "this" from the found Item_equal (as this equality not usefull). + */ + item_equal= NULL; + return this; + } + return item; }