Merge branch '10.1' of https://github.com/MariaDB/server into ok-debpkg-10.1

This commit is contained in:
Otto Kekäläinen 2015-09-07 22:21:35 +03:00
commit f8754d652e
45 changed files with 2199 additions and 336 deletions

View file

@ -100,7 +100,7 @@ struct my_rnd_struct;
enum Item_result
{
STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT,
TIME_RESULT,IMPOSSIBLE_RESULT
TIME_RESULT
};
typedef struct st_udf_args
{

View file

@ -547,7 +547,7 @@ struct my_rnd_struct;
enum Item_result
{
STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT,
TIME_RESULT,IMPOSSIBLE_RESULT
TIME_RESULT
};
typedef struct st_udf_args

View file

@ -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;

View file

@ -231,3 +231,138 @@ case t1.f1 when '00:00:00' then 1 end
1
NULL
drop table t1;
#
# Start of 10.1 test
#
#
# MDEV-8752 Wrong result for SELECT..WHERE CASE enum_field WHEN 1 THEN 1 ELSE 0 END AND a='5'
#
CREATE TABLE t1 (a ENUM('5','6') CHARACTER SET BINARY);
INSERT INTO t1 VALUES ('5'),('6');
SELECT * FROM t1 WHERE a='5';
a
5
SELECT * FROM t1 WHERE a=1;
a
5
SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END;
a
5
SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END AND a='5';
a
5
# Multiple comparison types in CASE, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END AND a='5';
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` = '5') and (case `test`.`t1`.`a` when 1 then 1 else 0 end))
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('a','b','100'));
INSERT INTO t1 VALUES ('a'),('b'),('100');
SELECT * FROM t1 WHERE a='a';
a
a
SELECT * FROM t1 WHERE CASE a WHEN 'a' THEN 1 ELSE 0 END;
a
a
SELECT * FROM t1 WHERE CASE a WHEN 'a' THEN 1 ELSE 0 END AND a='a';
a
a
# String comparison in CASE and in the equality, ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 'a' THEN 1 ELSE 0 END AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 'a')
SELECT * FROM t1 WHERE a=3;
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END;
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a=3;
a
100
# Integer comparison in CASE and in the equality, not ok to propagate
# ENUM does not support this type of propagation yet.
# This can change in the future. See MDEV-8748.
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a=3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((case `test`.`t1`.`a` when 3 then 1 else 0 end) and (`test`.`t1`.`a` = 3))
SELECT * FROM t1 WHERE a=3;
a
100
SELECT * FROM t1 WHERE CASE a WHEN '100' THEN 1 ELSE 0 END;
a
100
SELECT * FROM t1 WHERE CASE a WHEN '100' THEN 1 ELSE 0 END AND a=3;
a
100
# String comparison in CASE, integer comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN '100' THEN 1 ELSE 0 END AND a=3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((case `test`.`t1`.`a` when '100' then 1 else 0 end) and (`test`.`t1`.`a` = 3))
SELECT * FROM t1 WHERE a='100';
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END;
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a='100';
a
100
# Integer comparison in CASE, string comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a='100';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '100') and (case `test`.`t1`.`a` when 3 then 1 else 0 end))
SELECT * FROM t1 WHERE a='100';
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END;
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a='100';
a
100
# Multiple type comparison in CASE, string comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a='100';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '100') and (case `test`.`t1`.`a` when 3 then 1 when '100' then 1 else 0 end))
SELECT * FROM t1 WHERE a=3;
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END;
a
100
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a=3;
a
100
# Multiple type comparison in CASE, integer comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a=3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((case `test`.`t1`.`a` when 3 then 1 when '100' then 1 else 0 end) and (`test`.`t1`.`a` = 3))
DROP TABLE t1;
#
# End of MDEV-8752
#
#
# End of 10.1 test
#

View file

@ -604,3 +604,48 @@ where coalesce(message,0) <> 0;
id message
drop table t1,t2;
set optimizer_switch=@save_derived_optimizer_switch;
#
# Start of 10.1 tests
#
#
# MDEV-8747 Wrong result for SELECT..WHERE derived_table_column='a' AND derived_table_column<>_latin1'A' COLLATE latin1_bin
#
CREATE TABLE t1 (a VARCHAR(10));
INSERT INTO t1 VALUES ('a'),('A');
SELECT * FROM t1 WHERE a='a' AND a <> _latin1'A' COLLATE latin1_bin;
a
a
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='a' AND a <> _latin1'A' COLLATE latin1_bin;
a
a
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5';
a
5
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a=1;
a
5
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5' AND a=1;
a
5
DROP TABLE t1;
#
# MDEV-8749 Wrong result for SELECT..WHERE derived_table_enum_column='number' AND derived_table_enum_column OP number2
#
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5';
a
5
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a=1;
a
5
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5' AND a=1;
a
5
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -2289,20 +2289,16 @@ field1 field2
2004-10-11 18:13:00 1
2009-02-19 02:05:00 5
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'g'
Warning 1292 Truncated incorrect DOUBLE value: 'o'
Warning 1292 Truncated incorrect DOUBLE value: 'g'
Warning 1292 Truncated incorrect DOUBLE value: 'v'
SELECT alias2.f3 AS field1 , alias2.f1 AS field2 FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f1 = alias1.f2 AND alias2.f1 != alias1.f4 GROUP BY field1 , field2 ;
field1 field2
2004-10-11 18:13:00 1
2009-02-19 02:05:00 5
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'x'
Warning 1292 Truncated incorrect DOUBLE value: 'g'
Warning 1292 Truncated incorrect DOUBLE value: 'o'
Warning 1292 Truncated incorrect DOUBLE value: 'g'
Warning 1292 Truncated incorrect DOUBLE value: 'v'
SET SESSION SQL_MODE=default;
drop table t1;

View file

@ -97,6 +97,6 @@ FLUSH LOGS;
# Cleanup.
#
# reset variable value to pass testcase checks
SET @@global.max_allowed_packet = 1048576;
SET @@global.max_allowed_packet = 4194304;
DROP TABLE t1;
remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_big_1.out

View file

@ -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 (<cache>(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 (<cache>(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 (<cache>(length(DATE'2001-01-01')) = (8 + rand())))
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -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 (<cache>(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 (<cache>(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 (<cache>(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 (<cache>(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 (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand())))
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -2082,3 +2082,55 @@ DROP TABLE t1;
#
# End of 10.0 tests
#
#
# Start of 10.1 tests
#
#
# MDEV-8729 Wrong result for SELECT..WHERE HEX(enum_column)='61' AND enum_column='a '
#
CREATE TABLE t1 (a ENUM('a','A') CHARACTER SET latin1 COLLATE latin1_bin);
INSERT INTO t1 VALUES ('a'),('A');
SELECT * FROM t1 WHERE a='a ';
a
a
SELECT * FROM t1 WHERE HEX(a)='61';
a
a
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
a
a
# Can't propagate the equality into HEX(a), because binary collations still ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
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` = 'a ') and (hex(`test`.`t1`.`a`) = '61'))
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('a','a ') CHARACTER SET BINARY);
INSERT INTO t1 VALUES ('a'),('a ');
SELECT * FROM t1 WHERE a='a ';
a
a
SELECT * FROM t1 WHERE HEX(a)='61';
a
a
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
a
a
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
a
# Ok to propagate the equality into HEX(a), because "CHARACTER SET BINARY" does not ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
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` = 'a')
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
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
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -532,3 +532,98 @@ DROP TABLE t1,t2;
#
# End of 10.0 tests
#
#
# MDEV-8704 Wrong result for SELECT..WHERE LENGTH(double_column)!=6 AND double_column=100e0
#
CREATE TABLE t1 (a DOUBLE(9,2));
INSERT INTO t1 VALUES (100),(110);
SELECT * FROM t1 WHERE LENGTH(a)!=6;
a
SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0;
a
DROP TABLE t1;
CREATE TABLE t1 (a DOUBLE);
INSERT INTO t1 VALUES (100),(110);
SELECT * FROM t1 WHERE LENGTH(a)!=6;
a
100
110
SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0;
a
100
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0;
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` = 100e0)
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=100e0;
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` = 100e0) and (<cache>(length(100)) <> rand()))
DROP TABLE t1;
CREATE TABLE t1 (a DOUBLE(10,1));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=3;
a
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0;
a
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0;
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
# Notice 1.1 instead of 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10e0) and (<cache>(length(1.1)) <> rand()))
DROP TABLE t1;
CREATE TABLE t1 (a DOUBLE(10,2));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=4;
a
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0;
a
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0;
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
# Notice 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10e0) and (<cache>(length(1.10)) <> rand()))
DROP TABLE t1;
CREATE TABLE t1 (a DOUBLE(10,3));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=5;
a
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0;
a
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0;
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
# Notice 1.100 rather than 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10e0) and (<cache>(length(1.100)) <> rand()))
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -2078,3 +2078,72 @@ DROP TABLE t1,t2;
#
# End of 10.0 tests
#
#
# Start of 10.1 tests
#
#
# MDEV-8703 Wrong result for SELECT..WHERE LENGTH(decimal_10_1_column)!=3 AND decimal_10_1_column=1.10
#
CREATE TABLE t1 (a DECIMAL(10,1));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=3;
a
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10;
a
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
# Notice 1.1 instead of 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10) and (<cache>(length(1.1)) <> rand()))
DROP TABLE t1;
CREATE TABLE t1 (a DECIMAL(10,2));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=4;
a
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10;
a
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
# Notice 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10) and (<cache>(length(1.10)) <> rand()))
DROP TABLE t1;
CREATE TABLE t1 (a DECIMAL(10,3));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=5;
a
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10;
a
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
# Notice 1.100 rather than 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 1.10) and (<cache>(length(1.100)) <> rand()))
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -263,3 +263,55 @@ DROP TABLE t1;
#
# End of 10.0 tests
#
#
# Start of 10.1 tests
#
#
# MDEV-8729 Wrong result for SELECT..WHERE HEX(enum_column)='61' AND enum_column='a '
#
CREATE TABLE t1 (a SET('a','A') CHARACTER SET latin1 COLLATE latin1_bin);
INSERT INTO t1 VALUES ('a'),('A');
SELECT * FROM t1 WHERE a='a ';
a
a
SELECT * FROM t1 WHERE HEX(a)='61';
a
a
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
a
a
# Can't propagate the equality into HEX(a), because binary collations still ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
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` = 'a ') and (hex(`test`.`t1`.`a`) = '61'))
DROP TABLE t1;
CREATE TABLE t1 (a SET('a','a ') CHARACTER SET BINARY);
INSERT INTO t1 VALUES ('a'),('a ');
SELECT * FROM t1 WHERE a='a ';
a
a
SELECT * FROM t1 WHERE HEX(a)='61';
a
a
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
a
a
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
a
# Ok to propagate the equality into HEX(a), because "CHARACTER SET BINARY" does not ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
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` = 'a')
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
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
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -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 (<cache>(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 (<cache>(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 (<cache>(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 (<cache>(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 (<cache>(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 (<cache>(length(TIME'00:00:00')) = (30 + rand())))
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -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 (<cache>(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 (<cache>(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 (<cache>(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 (<cache>(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 (<cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = (40 + rand())))
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -4430,36 +4430,58 @@ CREATE TABLE t1 (a varchar(10), KEY (a)) ;
INSERT INTO t1 VALUES
('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM');
CREATE VIEW v1 AS SELECT * FROM t1;
# t1 and v1 should return the same result set
SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
a
KK
MM
ZZ
ZZ
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'VV'
SELECT * FROM t1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
a
KK
MM
ZZ
ZZ
# t1 and v1 should propagate constants in the same way
EXPLAIN EXTENDED
SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'VV'
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 'JJ')
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` > 'JJ') or ((`test`.`t1`.`a` = 'VV') and (`test`.`t1`.`a` <> 0)))
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` > 'JJ') or ((`test`.`t1`.`a` = 'VV') and (`test`.`t1`.`a` <> 0)))
# t1 and v1 should return the same result set
SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
a
KK
MM
ZZ
ZZ
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'VV'
SELECT * FROM t1 WHERE a > 'JJ' OR a AND a = 'VV';
a
KK
MM
ZZ
ZZ
# t1 and v1 should propagate constants in the same way
EXPLAIN EXTENDED
SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'VV'
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 'JJ')
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` > 'JJ') or ((`test`.`t1`.`a` = 'VV') and (`test`.`t1`.`a` <> 0)))
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a > 'JJ' OR a AND a = 'VV';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` > 'JJ') or ((`test`.`t1`.`a` = 'VV') and (`test`.`t1`.`a` <> 0)))
DROP VIEW v1;
DROP TABLE t1;
#
@ -5571,3 +5593,66 @@ drop view v3;
# -- End of 10.0 tests.
# -----------------------------------------------------------------
SET optimizer_switch=@save_optimizer_switch;
#
# Start of 10.1 tests
#
#
# MDEV-8747 Wrong result for SELECT..WHERE derived_table_column='a' AND derived_table_column<>_latin1'A' COLLATE latin1_bin
#
CREATE TABLE t1 (a varchar(10) character set cp1251 collate cp1251_ukrainian_ci, KEY (a)) ;
INSERT INTO t1 VALUES ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM'),('`1');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a <> 0 AND a = ' 1';
a
SELECT * FROM v1 WHERE a <> 0 AND a = ' 1';
a
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a='5' AND a<2;
a
5
SELECT * FROM v1 WHERE a='5' AND a<2;
a
5
DROP VIEW v1;
DROP TABLE t1;
#
# MDEV-8749 Wrong result for SELECT..WHERE derived_table_enum_column='number' AND derived_table_enum_column OP number2
#
CREATE TABLE t1 (a varchar(10) character set cp1251 collate cp1251_ukrainian_ci, KEY (a));
INSERT INTO t1 VALUES ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM'),('`1');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a <> 0 AND a = ' 1';
a
SELECT * FROM v1 WHERE a <> 0 AND a = ' 1';
a
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a='5' AND a<2;
a
5
SELECT * FROM v1 WHERE a='5' AND a<2;
a
5
DROP VIEW v1;
DROP TABLE t1;
#
# MDEV-8742 Wrong result for SELECT..WHERE view_latin1_swedish_ci_field='a' COLLATE latin1_bin
#
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
INSERT INTO t1 VALUES ('a'),('A');
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a='a';
SELECT * FROM v1 WHERE a=_latin1'a' COLLATE latin1_bin;
a
a
DROP VIEW v1;
DROP TABLE t1;
#
# End of 10.1 tests
#

View file

@ -3,6 +3,7 @@ call mtr.add_suppression("InnoDB: However key management plugin or used key_id 1
call mtr.add_suppression("InnoDB: Marking tablespace as missing. You may drop this table or install correct key management plugin and key file.");
call mtr.add_suppression(".*InnoDB: Cannot open table test/.* from the internal data dictionary of InnoDB though the .frm file for the table exists. See .* for how you can resolve the problem.");
call mtr.add_suppression("InnoDB: .ibd file is missing for table test/.*");
call mtr.add_suppression("Couldn't load plugins from 'file_key_management*");
CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB ENCRYPTION_KEY_ID=4;
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
select * from t1;

View file

@ -12,6 +12,8 @@ call mtr.add_suppression("InnoDB: However key management plugin or used key_id 1
call mtr.add_suppression("InnoDB: Marking tablespace as missing. You may drop this table or install correct key management plugin and key file.");
call mtr.add_suppression(".*InnoDB: Cannot open table test/.* from the internal data dictionary of InnoDB though the .frm file for the table exists. See .* for how you can resolve the problem.");
call mtr.add_suppression("InnoDB: .ibd file is missing for table test/.*");
# Suppression for builds where file_key_management plugin is linked statically
call mtr.add_suppression("Couldn't load plugins from 'file_key_management*");
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server

View file

@ -68,7 +68,8 @@ a
SELECT FOUND_ROWS();
FOUND_ROWS()
3
SET GLOBAL query_cache_size = 1024*1024;
SET GLOBAL query_cache_type = ON;
SET query_cache_type = ON;
SELECT SQL_CACHE * FROM t1, t2;
a b a b
1 z 1 z
@ -89,7 +90,7 @@ a b a b
200 bar 100 foobar
200 bar 200 bar
200 bar 200 bar
SET GLOBAL query_cache_size = 0;
SET GLOBAL query_cache_type = DEFAULT;
SELECT a+10 AS field1, CONCAT(b,':',b) AS field2 FROM t1
WHERE b > 'b' AND a IS NOT NULL
GROUP BY 2 DESC, field1 ASC

View file

@ -45,11 +45,11 @@ SELECT SQL_BIG_RESULT SQL_CALC_FOUND_ROWS DISTINCT(t2.a)
FROM t1 t1_1, t2, t1 t1_2;
SELECT FOUND_ROWS();
let $query_cache = `SELECT @@query_cache_size`;
SET GLOBAL query_cache_size = 1024*1024;
SET GLOBAL query_cache_type = ON;
SET query_cache_type = ON;
--sorted_result
SELECT SQL_CACHE * FROM t1, t2;
eval SET GLOBAL query_cache_size = $query_cache;
SET GLOBAL query_cache_type = DEFAULT;
# Combination of main clauses

View file

@ -193,3 +193,75 @@ insert t1 values ('00:00:00'),('00:01:00');
select case t1.f1 when '00:00:00' then 1 end from t1;
drop table t1;
--echo #
--echo # Start of 10.1 test
--echo #
--echo #
--echo # MDEV-8752 Wrong result for SELECT..WHERE CASE enum_field WHEN 1 THEN 1 ELSE 0 END AND a='5'
--echo #
CREATE TABLE t1 (a ENUM('5','6') CHARACTER SET BINARY);
INSERT INTO t1 VALUES ('5'),('6');
SELECT * FROM t1 WHERE a='5';
SELECT * FROM t1 WHERE a=1;
SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END;
SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END AND a='5';
--echo # Multiple comparison types in CASE, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 1 THEN 1 ELSE 0 END AND a='5';
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('a','b','100'));
INSERT INTO t1 VALUES ('a'),('b'),('100');
SELECT * FROM t1 WHERE a='a';
SELECT * FROM t1 WHERE CASE a WHEN 'a' THEN 1 ELSE 0 END;
SELECT * FROM t1 WHERE CASE a WHEN 'a' THEN 1 ELSE 0 END AND a='a';
--echo # String comparison in CASE and in the equality, ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 'a' THEN 1 ELSE 0 END AND a='a';
SELECT * FROM t1 WHERE a=3;
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END;
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a=3;
--echo # Integer comparison in CASE and in the equality, not ok to propagate
--echo # ENUM does not support this type of propagation yet.
--echo # This can change in the future. See MDEV-8748.
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a=3;
SELECT * FROM t1 WHERE a=3;
SELECT * FROM t1 WHERE CASE a WHEN '100' THEN 1 ELSE 0 END;
SELECT * FROM t1 WHERE CASE a WHEN '100' THEN 1 ELSE 0 END AND a=3;
--echo # String comparison in CASE, integer comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN '100' THEN 1 ELSE 0 END AND a=3;
SELECT * FROM t1 WHERE a='100';
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END;
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a='100';
--echo # Integer comparison in CASE, string comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 ELSE 0 END AND a='100';
SELECT * FROM t1 WHERE a='100';
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END;
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a='100';
--echo # Multiple type comparison in CASE, string comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a='100';
SELECT * FROM t1 WHERE a=3;
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END;
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a=3;
--echo # Multiple type comparison in CASE, integer comparison in the equality, not Ok to propagate
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE CASE a WHEN 3 THEN 1 WHEN '100' THEN 1 ELSE 0 END AND a=3;
DROP TABLE t1;
--echo #
--echo # End of MDEV-8752
--echo #
--echo #
--echo # End of 10.1 test
--echo #

View file

@ -539,3 +539,37 @@ where coalesce(message,0) <> 0;
drop table t1,t2;
set optimizer_switch=@save_derived_optimizer_switch;
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-8747 Wrong result for SELECT..WHERE derived_table_column='a' AND derived_table_column<>_latin1'A' COLLATE latin1_bin
--echo #
CREATE TABLE t1 (a VARCHAR(10));
INSERT INTO t1 VALUES ('a'),('A');
SELECT * FROM t1 WHERE a='a' AND a <> _latin1'A' COLLATE latin1_bin;
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='a' AND a <> _latin1'A' COLLATE latin1_bin;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5';
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a=1;
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5' AND a=1;
DROP TABLE t1;
--echo #
--echo # MDEV-8749 Wrong result for SELECT..WHERE derived_table_enum_column='number' AND derived_table_enum_column OP number2
--echo #
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5';
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a=1;
SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5' AND a=1;
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #

View file

@ -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 #

View file

@ -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 #

View file

@ -357,3 +357,34 @@ DROP TABLE t1;
--echo #
--echo # End of 10.0 tests
--echo #
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-8729 Wrong result for SELECT..WHERE HEX(enum_column)='61' AND enum_column='a '
--echo #
CREATE TABLE t1 (a ENUM('a','A') CHARACTER SET latin1 COLLATE latin1_bin);
INSERT INTO t1 VALUES ('a'),('A');
SELECT * FROM t1 WHERE a='a ';
SELECT * FROM t1 WHERE HEX(a)='61';
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
--echo # Can't propagate the equality into HEX(a), because binary collations still ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('a','a ') CHARACTER SET BINARY);
INSERT INTO t1 VALUES ('a'),('a ');
SELECT * FROM t1 WHERE a='a ';
SELECT * FROM t1 WHERE HEX(a)='61';
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
--echo # Ok to propagate the equality into HEX(a), because "CHARACTER SET BINARY" does not ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #

View file

@ -385,3 +385,67 @@ DROP TABLE t1,t2;
--echo #
--echo # End of 10.0 tests
--echo #
--echo #
--echo # MDEV-8704 Wrong result for SELECT..WHERE LENGTH(double_column)!=6 AND double_column=100e0
--echo #
# The original test case from the bug report
CREATE TABLE t1 (a DOUBLE(9,2));
INSERT INTO t1 VALUES (100),(110);
SELECT * FROM t1 WHERE LENGTH(a)!=6;
SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0;
DROP TABLE t1;
# DOUBLE with no specific precision
CREATE TABLE t1 (a DOUBLE);
INSERT INTO t1 VALUES (100),(110);
SELECT * FROM t1 WHERE LENGTH(a)!=6;
SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=6 AND a=100e0;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=100e0;
DROP TABLE t1;
# The constant scale is bigger than the field scale
CREATE TABLE t1 (a DOUBLE(10,1));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=3;
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10e0;
--echo # Notice 1.1 instead of 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
DROP TABLE t1;
# The constant scale is equal to the field scale
CREATE TABLE t1 (a DOUBLE(10,2));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=4;
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10e0;
--echo # Notice 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
DROP TABLE t1;
# The constant scale is smaller than the field scale
CREATE TABLE t1 (a DOUBLE(10,3));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=5;
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10e0;
--echo # Notice 1.100 rather than 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #

View file

@ -1622,3 +1622,52 @@ DROP TABLE t1,t2;
--echo #
--echo # End of 10.0 tests
--echo #
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-8703 Wrong result for SELECT..WHERE LENGTH(decimal_10_1_column)!=3 AND decimal_10_1_column=1.10
--echo #
# The constant scale is bigger than the field scale
CREATE TABLE t1 (a DECIMAL(10,1));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=3;
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=3 AND a=1.10;
--echo # Notice 1.1 instead of 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
DROP TABLE t1;
# The constant scale is equal to the field scale
CREATE TABLE t1 (a DECIMAL(10,2));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=4;
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=4 AND a=1.10;
--echo # Notice 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
DROP TABLE t1;
# The constant scale is smaller than the field scale
CREATE TABLE t1 (a DECIMAL(10,3));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
SELECT * FROM t1 WHERE LENGTH(a)!=5;
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=5 AND a=1.10;
--echo # Notice 1.100 rather than 1.10 in the final WHERE condition
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #

View file

@ -185,3 +185,35 @@ DROP TABLE t1;
--echo #
--echo # End of 10.0 tests
--echo #
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-8729 Wrong result for SELECT..WHERE HEX(enum_column)='61' AND enum_column='a '
--echo #
CREATE TABLE t1 (a SET('a','A') CHARACTER SET latin1 COLLATE latin1_bin);
INSERT INTO t1 VALUES ('a'),('A');
SELECT * FROM t1 WHERE a='a ';
SELECT * FROM t1 WHERE HEX(a)='61';
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
--echo # Can't propagate the equality into HEX(a), because binary collations still ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
DROP TABLE t1;
CREATE TABLE t1 (a SET('a','a ') CHARACTER SET BINARY);
INSERT INTO t1 VALUES ('a'),('a ');
SELECT * FROM t1 WHERE a='a ';
SELECT * FROM t1 WHERE HEX(a)='61';
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
--echo # Ok to propagate the equality into HEX(a), because "CHARACTER SET BINARY" does not ignore trailing spaces
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE HEX(a)='61' AND a='a ';
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #

View file

@ -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 #

View file

@ -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 #

View file

@ -4318,13 +4318,23 @@ INSERT INTO t1 VALUES
CREATE VIEW v1 AS SELECT * FROM t1;
--echo # t1 and v1 should return the same result set
SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
SELECT * FROM t1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
--echo # t1 and v1 should propagate constants in the same way
EXPLAIN EXTENDED
SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV';
--echo # t1 and v1 should return the same result set
SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
SELECT * FROM t1 WHERE a > 'JJ' OR a AND a = 'VV';
--echo # t1 and v1 should propagate constants in the same way
EXPLAIN EXTENDED
SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a > 'JJ' OR a AND a = 'VV';
DROP VIEW v1;
DROP TABLE t1;
@ -5450,3 +5460,60 @@ drop view v3;
--echo # -- End of 10.0 tests.
--echo # -----------------------------------------------------------------
SET optimizer_switch=@save_optimizer_switch;
--echo #
--echo # Start of 10.1 tests
--echo #
--echo #
--echo # MDEV-8747 Wrong result for SELECT..WHERE derived_table_column='a' AND derived_table_column<>_latin1'A' COLLATE latin1_bin
--echo #
CREATE TABLE t1 (a varchar(10) character set cp1251 collate cp1251_ukrainian_ci, KEY (a)) ;
INSERT INTO t1 VALUES ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM'),('`1');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a <> 0 AND a = ' 1';
SELECT * FROM v1 WHERE a <> 0 AND a = ' 1';
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a='5' AND a<2;
SELECT * FROM v1 WHERE a='5' AND a<2;
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # MDEV-8749 Wrong result for SELECT..WHERE derived_table_enum_column='number' AND derived_table_enum_column OP number2
--echo #
CREATE TABLE t1 (a varchar(10) character set cp1251 collate cp1251_ukrainian_ci, KEY (a));
INSERT INTO t1 VALUES ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM'),('`1');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a <> 0 AND a = ' 1';
SELECT * FROM v1 WHERE a <> 0 AND a = ' 1';
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a ENUM('5','6'));
INSERT INTO t1 VALUES ('5'),('6');
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 WHERE a='5' AND a<2;
SELECT * FROM v1 WHERE a='5' AND a<2;
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # MDEV-8742 Wrong result for SELECT..WHERE view_latin1_swedish_ci_field='a' COLLATE latin1_bin
--echo #
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
INSERT INTO t1 VALUES ('a'),('A');
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a='a';
SELECT * FROM v1 WHERE a=_latin1'a' COLLATE latin1_bin;
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # End of 10.1 tests
--echo #

View file

@ -1261,6 +1261,61 @@ bool Field::test_if_equality_guarantees_uniqueness(const Item *item) const
}
/**
Check whether a field item can be substituted for an equal item
@details
The function checks whether a substitution of a field item for
an equal item is valid.
@param arg *arg != NULL <-> the field is in the context
where substitution for an equal item is valid
@note
The following statement is not always true:
@n
x=y => F(x)=F(x/y).
@n
This means substitution of an item for an equal item not always
yields an equavalent condition. Here's an example:
@code
'a'='a '
(LENGTH('a')=1) != (LENGTH('a ')=2)
@endcode
Such a substitution is surely valid if either the substituted
field is not of a STRING type or if it is an argument of
a comparison predicate.
@retval
TRUE substitution is valid
@retval
FALSE otherwise
*/
bool Field::can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal)
{
DBUG_ASSERT(item_equal->compare_type() != STRING_RESULT);
DBUG_ASSERT(cmp_type() != STRING_RESULT);
switch (ctx.subst_constraint()) {
case ANY_SUBST:
/*
Disable const propagation for items used in different comparison contexts.
This must be done because, for example, Item_hex_string->val_int() is not
the same as (Item_hex_string->val_str() in BINARY column)->val_int().
We cannot simply disable the replacement in a particular context (
e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
Items don't know the context they are in and there are functions like
IF (<hex_string>, 'yes', 'no').
*/
return ctx.compare_type() == item_equal->compare_type();
case IDENTITY_SUBST:
return true;
}
return false;
}
/*
This handles all numeric and BIT data types.
*/
@ -1303,7 +1358,7 @@ Field_num::Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
}
void Field_num::prepend_zeros(String *value)
void Field_num::prepend_zeros(String *value) const
{
int diff;
if ((diff= (int) (field_length - value->length())) > 0)
@ -1317,6 +1372,52 @@ void Field_num::prepend_zeros(String *value)
}
}
/**
Convert a numeric value to a zero-filled string
@param[in] thd current thread
@param[in] item the item to convert
This function converts a numeric value to a string. In this conversion
the zero-fill flag of the field is taken into account.
This is required so the resulting string value can be used instead of
the field reference when propagating equalities.
*/
Item *Field_num::convert_zerofill_number_to_string(THD *thd, Item *item) const
{
char buff[MAX_FIELD_WIDTH],*pos;
String tmp(buff,sizeof(buff),Field_num::charset()), *res;
res= item->val_str(&tmp);
if (item->is_null())
return new (thd->mem_root) Item_null(thd);
else
{
prepend_zeros(res);
pos= (char *) sql_strmake (res->ptr(), res->length());
return new (thd->mem_root) Item_string(thd, pos, res->length(), Field_num::charset());
}
}
Item *Field_num::get_equal_zerofill_const_item(THD *thd, const Context &ctx,
Item_field *field_item,
Item *const_item)
{
switch (ctx.subst_constraint()) {
case IDENTITY_SUBST:
return convert_zerofill_number_to_string(thd, const_item);
case ANY_SUBST:
break;
}
DBUG_ASSERT(const_item->const_item());
DBUG_ASSERT(ctx.compare_type() != STRING_RESULT);
return field_item;
}
/**
Test if given number is a int.
@ -1884,6 +1985,23 @@ bool Field_str::test_if_equality_guarantees_uniqueness(const Item *item) const
}
bool Field_str::can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal)
{
DBUG_ASSERT(item_equal->compare_type() == STRING_RESULT);
switch (ctx.subst_constraint()) {
case ANY_SUBST:
return ctx.compare_type() == item_equal->compare_type() &&
(ctx.compare_type() != STRING_RESULT ||
ctx.compare_collation() == item_equal->compare_collation());
case IDENTITY_SUBST:
return ((charset()->state & MY_CS_BINSORT) &&
(charset()->state & MY_CS_NOPAD));
}
return false;
}
void Field_num::make_field(Send_field *field)
{
Field::make_field(field);
@ -3172,6 +3290,38 @@ Field_new_decimal::unpack(uchar* to, const uchar *from, const uchar *from_end,
return from+len;
}
Item *Field_new_decimal::get_equal_const_item(THD *thd, const Context &ctx,
Item_field *field_item,
Item *const_item)
{
if (flags & ZEROFILL_FLAG)
return Field_num::get_equal_zerofill_const_item(thd, ctx,
field_item, const_item);
switch (ctx.subst_constraint()) {
case IDENTITY_SUBST:
if (const_item->field_type() != MYSQL_TYPE_NEWDECIMAL ||
const_item->decimal_scale() != decimals())
{
my_decimal *val, val_buffer, val_buffer2;
if (!(val= const_item->val_decimal(&val_buffer)))
{
DBUG_ASSERT(0);
return const_item;
}
/* Truncate or extend the decimal value to the scale of the field */
my_decimal_round(E_DEC_FATAL_ERROR, val, decimals(), true, &val_buffer2);
return new (thd->mem_root) Item_decimal(thd, field_name, &val_buffer2,
decimals(), field_length);
}
break;
case ANY_SUBST:
break;
}
return const_item;
}
int Field_num::store_time_dec(MYSQL_TIME *ltime, uint dec_arg)
{
longlong v= TIME_to_ulonglong(ltime);
@ -4489,6 +4639,28 @@ bool Field_real::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
}
Item *Field_real::get_equal_const_item(THD *thd, const Context &ctx,
Item_field *field_item,
Item *const_item)
{
if (flags & ZEROFILL_FLAG)
return Field_num::get_equal_zerofill_const_item(thd, ctx,
field_item, const_item);
switch (ctx.subst_constraint()) {
case IDENTITY_SUBST:
if (const_item->decimal_scale() != Field_real::decimals())
{
double val= const_item->val_real();
return new (thd->mem_root) Item_float(thd, val, Field_real::decimals());
}
break;
case ANY_SUBST:
break;
}
return const_item;
}
String *Field_double::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
@ -5343,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(&ltime, 0) :
const_item->get_date(&ltime, 0))
return NULL;
return new (thd->mem_root) Item_datetime_literal(thd, &ltime,
decimals());
}
break;
case ANY_SUBST:
break;
}
return const_item;
}
/****************************************************************************
** time type
** In string context: HH:MM:SS
@ -5635,6 +5833,29 @@ int Field_time::store_decimal(const my_decimal *d)
return store_TIME_with_warning(&ltime, &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(&ltime, TIME_TIME_ONLY))
return NULL;
return new (thd->mem_root) Item_time_literal(thd, &ltime, decimals());
}
break;
case ANY_SUBST:
break;
}
return const_item;
}
uint32 Field_time_hires::pack_length() const
{
return time_hires_bytes[dec];
@ -6067,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(&ltime, 0) :
const_item->get_date(&ltime, 0))
return NULL;
return new (thd->mem_root) Item_date_literal(thd, &ltime);
}
break;
case ANY_SUBST:
break;
}
return const_item;
}
/****************************************************************************
** datetime type
** In string context: YYYY-MM-DD HH:MM:DD
@ -8616,7 +8860,6 @@ bool Field_enum::can_optimize_keypart_ref(const Item_bool_func *cond,
return true;
case STRING_RESULT:
return charset() == cond->compare_collation();
case IMPOSSIBLE_RESULT:
case ROW_RESULT:
DBUG_ASSERT(0);
break;

View file

@ -41,6 +41,7 @@ class Column_statistics;
class Column_statistics_collected;
class Item_func;
class Item_bool_func;
class Item_equal;
enum enum_check_fields
{
@ -50,6 +51,77 @@ enum enum_check_fields
};
/*
Common declarations for Field and Item
*/
class Value_source
{
public:
/*
The enumeration Subst_constraint is currently used only in implementations
of the virtual function subst_argument_checker.
*/
enum Subst_constraint
{
ANY_SUBST, /* Any substitution for a field is allowed */
IDENTITY_SUBST /* Substitution for a field is allowed if any two
different values of the field type are not equal */
};
/*
Item context attributes.
Comparison functions pass their attributes to propagate_equal_fields().
For exmple, for string comparison, the collation of the comparison
operation is important inside propagate_equal_fields().
*/
class Context
{
/*
Which type of propagation is allowed:
- ANY_SUBST (loose equality, according to the collation), or
- IDENTITY_SUBST (strict binary equality).
*/
Subst_constraint m_subst_constraint;
/*
Comparison type.
Impostant only when ANY_SUBSTS.
*/
Item_result m_compare_type;
/*
Collation of the comparison operation.
Important only when ANY_SUBST.
*/
CHARSET_INFO *m_compare_collation;
public:
Context(Subst_constraint subst, Item_result type, CHARSET_INFO *cs)
:m_subst_constraint(subst),
m_compare_type(type),
m_compare_collation(cs) { }
Subst_constraint subst_constraint() const { return m_subst_constraint; }
Item_result compare_type() const
{
DBUG_ASSERT(m_subst_constraint == ANY_SUBST);
return m_compare_type;
}
CHARSET_INFO *compare_collation() const
{
DBUG_ASSERT(m_subst_constraint == ANY_SUBST);
return m_compare_collation;
}
};
class Context_identity: public Context
{ // Use this to request only exact value, no invariants.
public:
Context_identity()
:Context(IDENTITY_SUBST, STRING_RESULT, &my_charset_bin) { }
};
class Context_boolean: public Context
{ // Use this when an item is [a part of] a boolean expression
public:
Context_boolean() :Context(ANY_SUBST, INT_RESULT, &my_charset_bin) { }
};
};
enum Derivation
{
DERIVATION_IGNORABLE= 6,
@ -61,6 +133,7 @@ enum Derivation
DERIVATION_EXPLICIT= 0
};
#define STORAGE_TYPE_MASK 7
#define COLUMN_FORMAT_MASK 7
#define COLUMN_FORMAT_SHIFT 3
@ -287,7 +360,7 @@ public:
}
};
class Field
class Field: public Value_source
{
Field(const Item &); /* Prevent use of these */
void operator=(Field &);
@ -1027,6 +1100,13 @@ public:
*/
virtual bool test_if_equality_guarantees_uniqueness(const Item *const_item)
const;
virtual bool can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item);
virtual Item *get_equal_const_item(THD *thd, const Context &ctx,
Item_field *field_item, Item *const_item)
{
return const_item;
}
virtual bool can_optimize_keypart_ref(const Item_bool_func *cond,
const Item *item) const;
virtual bool can_optimize_hash_join(const Item_bool_func *cond,
@ -1126,6 +1206,11 @@ protected:
class Field_num :public Field {
protected:
Item *convert_zerofill_number_to_string(THD *thd, Item *item) const;
Item *get_equal_zerofill_const_item(THD *thd, const Context &ctx,
Item_field *field_item,
Item *const_item);
public:
const uint8 dec;
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
@ -1137,7 +1222,14 @@ public:
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; }
CHARSET_INFO *charset(void) const { return &my_charset_numeric; }
void prepend_zeros(String *value);
void prepend_zeros(String *value) const;
Item *get_equal_const_item(THD *thd, const Context &ctx,
Item_field *field_item, Item *const_item)
{
return (flags & ZEROFILL_FLAG) ?
get_equal_zerofill_const_item(thd, ctx, field_item, const_item) :
const_item;
}
void add_zerofill_and_unsigned(String &res) const;
friend class Create_field;
void make_field(Send_field *);
@ -1172,6 +1264,8 @@ protected:
CHARSET_INFO *field_charset;
enum Derivation field_derivation;
public:
bool can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal);
Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg, CHARSET_INFO *charset);
@ -1269,6 +1363,8 @@ public:
my_decimal *val_decimal(my_decimal *);
uint32 max_display_length() { return field_length; }
uint size_of() const { return sizeof(*this); }
Item *get_equal_const_item(THD *thd, const Context &ctx,
Item_field *field_item, Item *const_item);
};
@ -1354,6 +1450,8 @@ public:
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data);
static Field *create_from_item(MEM_ROOT *root, Item *);
Item *get_equal_const_item(THD *thd, const Context &ctx,
Item_field *field_item, Item *const_item);
};
@ -1690,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,
@ -1835,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); }
};
@ -2023,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);
};
@ -2066,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);
};
@ -2224,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); }
};

View file

@ -97,7 +97,6 @@ bool Item::val_bool()
return val_real() != 0.0;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return 0; // Wrong (but safe)
}
@ -422,7 +421,6 @@ Item::Item(THD *thd):
maybe_null=null_value=with_sum_func=with_field=0;
in_rollup= 0;
with_subselect= 0;
cmp_context= IMPOSSIBLE_RESULT;
/* Initially this item is not attached to any JOIN_TAB. */
join_tab_idx= MAX_TABLES;
@ -468,8 +466,7 @@ Item::Item(THD *thd, Item *item):
with_field(item->with_field),
fixed(item->fixed),
is_autogenerated_name(item->is_autogenerated_name),
with_subselect(item->has_subquery()),
cmp_context(item->cmp_context)
with_subselect(item->has_subquery())
{
next= thd->free_list; // Put in free list
thd->free_list= this;
@ -545,7 +542,6 @@ void Item::print_value(String *str)
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
}
@ -636,7 +632,7 @@ Item_result Item::cmp_type() const
return TIME_RESULT;
};
DBUG_ASSERT(0);
return IMPOSSIBLE_RESULT;
return STRING_RESULT;
}
/**
@ -2598,7 +2594,6 @@ bool Item_field::val_bool_result()
return result_field->val_real() != 0.0;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return 0; // Shut up compiler
}
@ -3398,7 +3393,6 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
set_null();
}
@ -4017,7 +4011,6 @@ Item_copy *Item_copy::create(THD *thd, Item *item)
return new (mem_root) Item_copy_decimal(thd, item);
case TIME_RESULT:
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT (0);
}
/* should not happen */
@ -5337,79 +5330,6 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
}
/**
Check whether a field item can be substituted for an equal item
@details
The function checks whether a substitution of a field item for
an equal item is valid.
@param arg *arg != NULL <-> the field is in the context
where substitution for an equal item is valid
@note
The following statement is not always true:
@n
x=y => F(x)=F(x/y).
@n
This means substitution of an item for an equal item not always
yields an equavalent condition. Here's an example:
@code
'a'='a '
(LENGTH('a')=1) != (LENGTH('a ')=2)
@endcode
Such a substitution is surely valid if either the substituted
field is not of a STRING type or if it is an argument of
a comparison predicate.
@retval
TRUE substitution is valid
@retval
FALSE otherwise
*/
bool Item_field::can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item_equal)
{
if (cmp_context == STRING_RESULT &&
ctx.compare_collation() != item_equal->compare_collation())
return false;
return ctx.subst_constraint() == ANY_SUBST ||
field->cmp_type() != STRING_RESULT ||
((field->charset()->state & MY_CS_BINSORT) &&
(field->charset()->state & MY_CS_NOPAD));
}
/**
Convert a numeric value to a zero-filled string
@param[in,out] item the item to operate on
@param field The field that this value is equated to
This function converts a numeric value to a string. In this conversion
the zero-fill flag of the field is taken into account.
This is required so the resulting string value can be used instead of
the field reference when propagating equalities.
*/
static void convert_zerofill_number_to_string(THD *thd, Item **item, Field_num *field)
{
char buff[MAX_FIELD_WIDTH],*pos;
String tmp(buff,sizeof(buff), field->charset()), *res;
res= (*item)->val_str(&tmp);
if ((*item)->is_null())
*item= new (thd->mem_root) Item_null(thd);
else
{
field->prepend_zeros(res);
pos= (char *) sql_strmake (res->ptr(), res->length());
*item= new (thd->mem_root) Item_string(thd, pos, res->length(), field->charset());
}
}
/**
Set a pointer to the multiple equality the field reference belongs to
(if any).
@ -5438,36 +5358,38 @@ Item *Item_field::propagate_equal_fields(THD *thd,
const Context &ctx,
COND_EQUAL *arg)
{
if (no_const_subst)
if (no_const_subst || !(item_equal= find_item_equal(arg)))
return this;
item_equal= find_item_equal((COND_EQUAL *) arg);
Item *item= 0;
if (item_equal)
if (!field->can_be_substituted_to_equal_item(ctx, item_equal))
{
if (!can_be_substituted_to_equal_item(ctx, item_equal))
{
item_equal= NULL;
return this;
}
item= item_equal->get_const();
item_equal= NULL;
return this;
}
/*
Disable const propagation for items used in different comparison contexts.
This must be done because, for example, Item_hex_string->val_int() is not
the same as (Item_hex_string->val_str() in BINARY column)->val_int().
We cannot simply disable the replacement in a particular context (
e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since
Items don't know the context they are in and there are functions like
IF (<hex_string>, 'yes', 'no').
*/
if (!item || !has_compatible_context(item))
item= this;
else if (field && (field->flags & ZEROFILL_FLAG) && IS_NUM(field->type()))
Item *item= item_equal->get_const();
if (!item)
{
if (item && (cmp_context == STRING_RESULT || cmp_context == IMPOSSIBLE_RESULT))
convert_zerofill_number_to_string(thd, &item, (Field_num *)field);
else
item= this;
/*
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;
}
@ -5521,8 +5443,19 @@ Item *Item_field::replace_equal_field(THD *thd, uchar *arg)
Item *const_item2= item_equal->get_const();
if (const_item2)
{
if (!has_compatible_context(const_item2))
return this;
/*
Currently we don't allow to create Item_equal with compare_type()
different from its Item_field's cmp_type().
Field_xxx::test_if_equality_guarantees_uniqueness() prevent this.
Also, Item_field::propagate_equal_fields() does not allow to assign
this->item_equal to any instances of Item_equal if "this" is used
in a non-native comparison context, or with an incompatible collation.
So the fact that we have (item_equal != NULL) means that the currently
processed function (the owner of "this") uses the field in its native
comparison context, and it's safe to replace it to the constant from
item_equal.
*/
DBUG_ASSERT(cmp_type() == item_equal->compare_type());
return const_item2;
}
Item_field *subst=
@ -5588,7 +5521,6 @@ enum_field_types Item::field_type() const
case REAL_RESULT: return MYSQL_TYPE_DOUBLE;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return MYSQL_TYPE_VARCHAR;
}
@ -7373,7 +7305,6 @@ bool Item_ref::val_bool_result()
return result_field->val_real() != 0.0;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
}
@ -8737,9 +8668,6 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
(Item*) new (mem_root) Item_decimal(thd, name, result, length, decimals));
break;
}
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
break;
}
if (new_item)
thd->change_item_tree(ref, new_item);
@ -8891,9 +8819,6 @@ Item_cache* Item_cache::get_cache(THD *thd, const Item *item,
return new (mem_root) Item_cache_row(thd);
case TIME_RESULT:
return new (mem_root) Item_cache_temporal(thd, item->field_type());
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
break;
}
return 0; // Impossible
}
@ -9527,7 +9452,6 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
return MYSQL_TYPE_NEWDECIMAL;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
return MYSQL_TYPE_VAR_STRING;
}

View file

@ -602,7 +602,7 @@ public:
};
class Item: public Type_std_attributes
class Item: public Value_source, public Type_std_attributes
{
Item(const Item &); /* Prevent use of these */
void operator=(Item &);
@ -693,7 +693,6 @@ public:
bool with_subselect; /* If this item is a subselect or some
of its arguments is or contains a
subselect */
Item_result cmp_context; /* Comparison context */
// alloc & destruct is done as start of select using sql_alloc
Item(THD *thd);
/*
@ -1418,47 +1417,6 @@ public:
return FALSE;
}
/*
The enumeration Subst_constraint is currently used only in implementations
of the virtual function subst_argument_checker.
*/
enum Subst_constraint
{
ANY_SUBST, /* Any substitution for a field is allowed */
IDENTITY_SUBST /* Substitution for a field is allowed if any two
different values of the field type are not equal */
};
/*
Item context attributes.
Comparison functions pass their attributes to propagate_equal_fields().
For exmple, for string comparison, the collation of the comparison
operation is important inside propagate_equal_fields().
TODO: We should move Item::cmp_context to from Item to Item::Context
eventually.
*/
class Context
{
/*
Which type of propagation is allowed:
- SUBST_ANY (loose equality, according to the collation), or
- SUBST_IDENTITY (strict binary equality).
*/
Subst_constraint m_subst_constraint;
/*
Collation of the comparison operation.
Important only when SUBST_ANY.
*/
CHARSET_INFO *m_compare_collation;
public:
Context(Subst_constraint subst, CHARSET_INFO *cs)
:m_subst_constraint(subst), m_compare_collation(cs) { }
Context(Subst_constraint subst)
:m_subst_constraint(subst), m_compare_collation(&my_charset_bin) { }
Subst_constraint subst_constraint() const { return m_subst_constraint; }
CHARSET_INFO *compare_collation() const { return m_compare_collation; }
};
virtual Item* propagate_equal_fields(THD*, const Context &, COND_EQUAL *)
{
return this;
@ -1620,18 +1578,6 @@ public:
{
return 0;
}
/**
Check whether this and the given item has compatible comparison context.
Used by the equality propagation. See Item_field::propagate_equal_fields()
@return
TRUE if the context is the same
FALSE otherwise.
*/
inline bool has_compatible_context(Item *item) const
{
return cmp_context == IMPOSSIBLE_RESULT || item->cmp_context == cmp_context;
}
/**
Test whether an expression is expensive to compute. Used during
optimization to avoid computing expensive expressions during this
@ -2302,8 +2248,6 @@ public:
class Item_field :public Item_ident
{
bool can_be_substituted_to_equal_item(const Context &ctx,
const Item_equal *item);
protected:
void set_field(Field *field);
public:

View file

@ -482,9 +482,8 @@ void Item_func::convert_const_compared_to_int_field(THD *thd)
{
Item_field *field_item= (Item_field*) (args[field]->real_item());
if ((field_item->field_type() == MYSQL_TYPE_LONGLONG ||
field_item->field_type() == MYSQL_TYPE_YEAR) &&
convert_const_to_int(thd, field_item, &args[!field]))
args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
field_item->field_type() == MYSQL_TYPE_YEAR))
convert_const_to_int(thd, field_item, &args[!field]);
}
}
}
@ -499,8 +498,6 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp)
agg_arg_charsets_for_comparison(cmp->cmp_collation, args, 2))
return true;
args[0]->cmp_context= args[1]->cmp_context= item_cmp_type(args[0], args[1]);
// Convert constants when compared to int/year field
DBUG_ASSERT(functype() != LIKE_FUNC);
convert_const_compared_to_int_field(thd);
@ -551,10 +548,8 @@ int Arg_comparator::set_compare_func(Item_func_or_sum *item, Item_result type)
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
return 1;
}
if (comparators[i].set_cmp_func_and_arg_cmp_context(owner,
(*a)->addr(i),
(*b)->addr(i),
set_null))
if (comparators[i].set_cmp_func(owner, (*a)->addr(i),
(*b)->addr(i), set_null))
return 1;
}
break;
@ -617,9 +612,6 @@ int Arg_comparator::set_compare_func(Item_func_or_sum *item, Item_result type)
}
break;
}
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
break;
}
return 0;
}
@ -736,6 +728,7 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
set_null= set_null && owner_arg;
a= a1;
b= a2;
m_compare_type= type;
if (type == STRING_RESULT &&
(*a)->result_type() == STRING_RESULT &&
@ -2199,8 +2192,7 @@ void Item_func_between::fix_length_and_dec()
return;
if (agg_cmp_type(&m_compare_type, args, 3))
return;
args[0]->cmp_context= args[1]->cmp_context= args[2]->cmp_context=
m_compare_type;
if (m_compare_type == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, 3))
return;
@ -2363,7 +2355,6 @@ longlong Item_func_between::val_int()
break;
}
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
null_value= 1;
return 0;
@ -2422,7 +2413,6 @@ Item_func_case_abbreviation2::fix_length_and_dec2(Item **args)
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
fix_char_length(char_length);
@ -2779,7 +2769,7 @@ Item_func_nullif::is_null()
Item_func_case::Item_func_case(THD *thd, List<Item> &list,
Item *first_expr_arg, Item *else_expr_arg):
Item_func_hybrid_field_type(thd), first_expr_num(-1), else_expr_num(-1),
left_cmp_type(INT_RESULT), case_item(0)
left_cmp_type(INT_RESULT), case_item(0), m_found_types(0)
{
ncases= list.elements;
if (first_expr_arg)
@ -3010,9 +3000,9 @@ void Item_func_case::fix_length_and_dec()
{
Item **agg= arg_buffer;
uint nagg;
uint found_types= 0;
THD *thd= current_thd;
m_found_types= 0;
if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
maybe_null= 1;
@ -3079,14 +3069,14 @@ void Item_func_case::fix_length_and_dec()
for (nagg= 0; nagg < ncases/2 ; nagg++)
agg[nagg+1]= args[nagg*2];
nagg++;
if (!(found_types= collect_cmp_types(agg, nagg)))
if (!(m_found_types= collect_cmp_types(agg, nagg)))
return;
Item *date_arg= 0;
if (found_types & (1U << TIME_RESULT))
if (m_found_types & (1U << TIME_RESULT))
date_arg= find_date_time_item(args, arg_count, 0);
if (found_types & (1U << STRING_RESULT))
if (m_found_types & (1U << STRING_RESULT))
{
/*
If we'll do string comparison, we also need to aggregate
@ -3127,7 +3117,7 @@ void Item_func_case::fix_length_and_dec()
for (i= 0; i <= (uint)TIME_RESULT; i++)
{
if (found_types & (1U << i) && !cmp_items[i])
if (m_found_types & (1U << i) && !cmp_items[i])
{
DBUG_ASSERT((Item_result)i != ROW_RESULT);
@ -3137,18 +3127,93 @@ void Item_func_case::fix_length_and_dec()
return;
}
}
/*
Set cmp_context of all WHEN arguments. This prevents
Item_field::propagate_equal_fields() from transforming a
zerofill argument into a string constant. Such a change would
require rebuilding cmp_items.
*/
for (i= 0; i < ncases; i+= 2)
args[i]->cmp_context= item_cmp_type(left_cmp_type, args[i]);
}
}
Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
if (first_expr_num == -1)
{
// None of the arguments are in a comparison context
Item_args::propagate_equal_fields(thd, Context_identity(), cond);
return this;
}
for (uint i= 0; i < arg_count; i++)
{
/*
Even "i" values cover items that are in a comparison context:
CASE x0 WHEN x1 .. WHEN x2 .. WHEN x3 ..
Odd "i" values cover items that are not in comparison:
CASE ... THEN y1 ... THEN y2 ... THEN y3 ... ELSE y4 END
*/
Item *new_item= 0;
if ((int) i == first_expr_num) // Then CASE (the switch) argument
{
/*
Cannot replace the CASE (the switch) argument if
there are multiple comparison types were found, or found a single
comparison type that is not equal to args[0]->cmp_type().
- Example: multiple comparison types, can't propagate:
WHERE CASE str_column
WHEN 'string' THEN TRUE
WHEN 1 THEN TRUE
ELSE FALSE END;
- Example: a single incompatible comparison type, can't propagate:
WHERE CASE str_column
WHEN DATE'2001-01-01' THEN TRUE
ELSE FALSE END;
- Example: a single incompatible comparison type, can't propagate:
WHERE CASE str_column
WHEN 1 THEN TRUE
ELSE FALSE END;
- Example: a single compatible comparison type, ok to propagate:
WHERE CASE str_column
WHEN 'str1' THEN TRUE
WHEN 'str2' THEN TRUE
ELSE FALSE END;
*/
if (m_found_types == (1UL << left_cmp_type))
new_item= args[i]->propagate_equal_fields(thd,
Context(
ANY_SUBST,
left_cmp_type,
cmp_collation.collation),
cond);
}
else if ((i % 2) == 0) // WHEN arguments
{
/*
These arguments are in comparison.
Allow invariants of the same value during propagation.
Note, as we pass ANY_SUBST, none of the WHEN arguments will be
replaced to zero-filled constants (only IDENTITY_SUBST allows this).
Such a change for WHEN arguments would require rebuilding cmp_items.
*/
Item_result tmp_cmp_type= item_cmp_type(args[first_expr_num], args[i]);
new_item= args[i]->propagate_equal_fields(thd,
Context(
ANY_SUBST,
tmp_cmp_type,
cmp_collation.collation),
cond);
}
else // THEN and ELSE arguments (they are not in comparison)
{
new_item= args[i]->propagate_equal_fields(thd, Context_identity(), cond);
}
if (new_item && new_item != args[i])
thd->change_item_tree(&args[i], new_item);
}
return this;
}
uint Item_func_case::decimal_precision() const
{
int max_int_part=0;
@ -3305,7 +3370,6 @@ void Item_func_coalesce::fix_length_and_dec()
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
}
@ -3669,9 +3733,6 @@ cmp_item* cmp_item::get_comparator(Item_result type, Item *warn_item,
case TIME_RESULT:
DBUG_ASSERT(warn_item);
return new cmp_item_datetime(warn_item);
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
break;
}
return 0; // to satisfy compiler :)
}
@ -4000,7 +4061,6 @@ void Item_func_in::fix_length_and_dec()
if (m_compare_type == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
return;
args[0]->cmp_context= m_compare_type;
arg_types_compatible= TRUE;
if (m_compare_type == ROW_RESULT)
@ -4095,9 +4155,6 @@ void Item_func_in::fix_length_and_dec()
date_arg= find_date_time_item(args, arg_count, 0);
array= new (thd->mem_root) in_datetime(date_arg, arg_count - 1);
break;
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
break;
}
if (array && !(thd->is_fatal_error)) // If not EOM
{
@ -4132,16 +4189,6 @@ void Item_func_in::fix_length_and_dec()
}
}
}
/*
Set cmp_context of all arguments. This prevents
Item_field::propagate_equal_fields() from transforming a zerofill integer
argument into a string constant. Such a change would require rebuilding
cmp_itmes.
*/
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
{
arg[0]->cmp_context= item_cmp_type(left_cmp_type, arg[0]);
}
max_length= 1;
}
@ -4609,7 +4656,7 @@ Item *Item_cond::propagate_equal_fields(THD *thd,
is not important at this point. Item_func derivants will create and
pass their own context to the arguments.
*/
Item *new_item= item->propagate_equal_fields(thd, ANY_SUBST, cond);
Item *new_item= item->propagate_equal_fields(thd, Context_boolean(), cond);
if (new_item && new_item != item)
thd->change_item_tree(li.ref(), new_item);
}
@ -5810,6 +5857,7 @@ Item_equal::Item_equal(THD *thd, Item *f1, Item *f2, bool with_const_item):
equal_items.push_back(f1, thd->mem_root);
equal_items.push_back(f2, thd->mem_root);
compare_as_dates= with_const_item && f2->cmp_type() == TIME_RESULT;
cmp.set_compare_type(item_cmp_type(f1, f2));
upper_levels= NULL;
}
@ -5839,6 +5887,7 @@ Item_equal::Item_equal(THD *thd, Item_equal *item_equal):
}
with_const= item_equal->with_const;
compare_as_dates= item_equal->compare_as_dates;
cmp.set_compare_type(item_equal->cmp.compare_type());
cond_false= item_equal->cond_false;
upper_levels= item_equal->upper_levels;
}

View file

@ -47,6 +47,7 @@ typedef int (*Item_field_cmpfunc)(Item *f1, Item *f2, void *arg);
class Arg_comparator: public Sql_alloc
{
Item **a, **b;
Item_result m_compare_type;
arg_cmp_func func;
Item_func_or_sum *owner;
bool set_null; // TRUE <=> set owner->null_value
@ -68,9 +69,11 @@ public:
/* Allow owner function to use string buffers. */
String value1, value2;
Arg_comparator(): set_null(TRUE), comparators(0), thd(0),
Arg_comparator(): m_compare_type(STRING_RESULT),
set_null(TRUE), comparators(0), thd(0),
a_cache(0), b_cache(0) {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), set_null(TRUE),
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2),
m_compare_type(STRING_RESULT), set_null(TRUE),
comparators(0), thd(0), a_cache(0), b_cache(0) {};
private:
@ -78,23 +81,16 @@ private:
Item **a1, Item **a2,
Item_result type);
public:
void set_compare_type(Item_result type)
{
m_compare_type= type;
}
inline int set_cmp_func(Item_func_or_sum *owner_arg,
Item **a1, Item **a2, bool set_null_arg)
{
set_null= set_null_arg;
return set_cmp_func(owner_arg, a1, a2, item_cmp_type(*a1, *a2));
}
int set_cmp_func_and_arg_cmp_context(Item_func_or_sum *owner_arg,
Item **a1, Item **a2,
bool set_null_arg)
{
set_null= set_null_arg;
Item_result type= item_cmp_type(*a1, *a2);
int rc= set_cmp_func(owner_arg, a1, a2, type);
if (!rc)
(*a1)->cmp_context= (*a2)->cmp_context= type;
return rc;
}
inline int compare() { return (this->*func)(); }
int compare_string(); // compare args[0] & args[1]
@ -128,6 +124,7 @@ public:
return (owner->type() == Item::FUNC_ITEM &&
((Item_func*)owner)->functype() == Item_func::EQUAL_FUNC);
}
Item_result compare_type() const { return m_compare_type; }
void cleanup()
{
delete [] comparators;
@ -367,6 +364,20 @@ public:
COND *remove_eq_conds(THD *thd, Item::cond_result *cond_value,
bool top_level);
bool count_sargable_conds(uchar *arg);
/*
Specifies which result type the function uses to compare its arguments.
This method is used in equal field propagation.
*/
virtual Item_result compare_type() const
{
/*
Have STRING_RESULT by default, which means the function compares
val_str() results of the arguments. This is suitable for Item_func_like
and for Item_func_spatial_rel.
Note, Item_bool_rowready_func2 overrides this default behaviour.
*/
return STRING_RESULT;
}
};
class Item_bool_rowready_func2 :public Item_bool_func2
@ -388,7 +399,9 @@ public:
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST, compare_collation()),
Context(ANY_SUBST,
cmp.compare_type(),
compare_collation()),
cond);
return this;
}
@ -397,16 +410,9 @@ public:
{
return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true);
}
bool set_cmp_func_and_arg_cmp_context()
{
if (set_cmp_func())
return true;
tmp_arg[0]->cmp_context= tmp_arg[1]->cmp_context=
item_cmp_type(tmp_arg[0], tmp_arg[1]);
return false;
}
CHARSET_INFO *compare_collation() const
{ return cmp.cmp_collation.collation; }
Item_result compare_type() const { return cmp.compare_type(); }
Arg_comparator *get_comparator() { return &cmp; }
void cleanup()
{
@ -439,14 +445,9 @@ public:
Item *neg_transformer(THD *thd);
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
Item_args::propagate_equal_fields(thd, ANY_SUBST, cond);
Item_args::propagate_equal_fields(thd, Context_boolean(), cond);
return this;
}
void fix_length_and_dec()
{
Item_bool_func::fix_length_and_dec();
args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
}
};
class Item_func_not :public Item_bool_func
@ -729,13 +730,7 @@ public:
}
bool eq(const Item *item, bool binary_cmp) const;
CHARSET_INFO *compare_collation() const { return cmp_collation.collation; }
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST, compare_collation()),
cond);
return this;
}
Item* propagate_equal_fields(THD *, const Context &, COND_EQUAL *) = 0;
};
@ -762,6 +757,15 @@ public:
uint *and_level, table_map usable_tables,
SARGABLE_PARAM **sargables);
SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST,
m_compare_type,
compare_collation()),
cond);
return this;
}
};
@ -931,6 +935,15 @@ public:
table_map not_null_tables() const { return 0; }
bool is_null();
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST,
cmp.compare_type(),
cmp.cmp_collation.collation),
cond);
return this;
}
};
@ -1331,6 +1344,7 @@ class Item_func_case :public Item_func_hybrid_field_type
cmp_item *cmp_items[6]; /* For all result types */
cmp_item *case_item;
Item **arg_buffer;
uint m_found_types;
public:
Item_func_case(THD *thd, List<Item> &list, Item *first_expr_arg,
Item *else_expr_arg);
@ -1350,6 +1364,7 @@ public:
void cleanup();
void agg_str_lengths(Item *arg);
void agg_num_lengths(Item *arg);
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond);
};
/*
@ -1416,16 +1431,19 @@ public:
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{
/*
In case when arg_types_compatible is false,
fix_length_and_dec() leaves args[0]->cmp_context equal to
IMPOSSIBLE_CONTEXT. In this case it's not safe to replace the field to an
equal constant, because Item_field::can_be_substituted_to_equal_item()
won't be able to check compatibility between
Item_equal->compare_collation() and this->compare_collation().
TODO: enable propagation of the args[i>0] arguments even if
!arg_types_compatible. See MDEV-8755.
Note, we pass ANY_SUBST, this makes sure that non of the args
will be replaced to a zero-filled Item_string.
Such a change would require rebuilding of cmp_items.
*/
return arg_types_compatible ?
Item_func_opt_neg::propagate_equal_fields(thd, ctx, cond) :
this;
if (arg_types_compatible)
Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST,
m_compare_type,
compare_collation()),
cond);
return this;
}
virtual void print(String *str, enum_query_type query_type);
enum Functype functype() const { return IN_FUNC; }
@ -1684,7 +1702,8 @@ public:
if ((flags & MY_CS_NOPAD) && !(flags & MY_CS_NON1TO1))
Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST,
compare_collation()),
STRING_RESULT,
compare_collation()),
cond);
return this;
}
@ -1693,7 +1712,6 @@ public:
void fix_length_and_dec()
{
max_length= 1;
args[0]->cmp_context= args[1]->cmp_context= STRING_RESULT;
agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
void cleanup();
@ -2084,6 +2102,7 @@ public:
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(THD *thd, Item_transformer transformer, uchar *arg);
virtual void print(String *str, enum_query_type query_type);
Item_result compare_type() const { return cmp.compare_type(); }
CHARSET_INFO *compare_collation() const;
void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }

View file

@ -545,7 +545,6 @@ Field *Item_func::tmp_table_field(TABLE *table)
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
// This case should never be chosen
DBUG_ASSERT(0);
field= 0;
@ -859,7 +858,6 @@ void Item_func_num1::fix_length_and_dec()
max_length= args[0]->max_length;
break;
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s",
@ -920,7 +918,6 @@ String *Item_func_hybrid_result_type::val_str(String *str)
return str_op(&str_value);
case TIME_RESULT:
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return str;
@ -969,7 +966,6 @@ double Item_func_hybrid_result_type::val_real()
}
case TIME_RESULT:
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return 0.0;
@ -1018,7 +1014,6 @@ longlong Item_func_hybrid_result_type::val_int()
}
case TIME_RESULT:
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return 0;
@ -1070,7 +1065,6 @@ my_decimal *Item_func_hybrid_result_type::val_decimal(my_decimal *decimal_value)
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
return val;
@ -1124,7 +1118,6 @@ bool Item_func_hybrid_result_type::get_date(MYSQL_TIME *ltime,
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
@ -1876,7 +1869,6 @@ void Item_func_div::fix_length_and_dec()
case STRING_RESULT:
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
maybe_null= 1; // devision by zero
@ -2452,7 +2444,6 @@ void Item_func_int_val::fix_length_and_dec()
}
break;
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s",
@ -2634,7 +2625,6 @@ void Item_func_round::fix_length_and_dec()
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); /* This result type isn't handled */
}
}
@ -3016,7 +3006,6 @@ String *Item_func_min_max::val_str(String *str)
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
return 0;
}
@ -3614,7 +3603,6 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
break;
}
@ -3693,7 +3681,6 @@ bool udf_handler::get_arguments()
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
break;
}
@ -4530,7 +4517,6 @@ longlong Item_func_benchmark::val_int()
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
return 0;
}
@ -4969,7 +4955,6 @@ double user_var_entry::val_real(bool *null_value)
return my_atof(value); // This is null terminated
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
}
@ -5002,7 +4987,6 @@ longlong user_var_entry::val_int(bool *null_value) const
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
}
@ -5037,7 +5021,6 @@ String *user_var_entry::val_str(bool *null_value, String *str,
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
}
@ -5066,7 +5049,6 @@ my_decimal *user_var_entry::val_decimal(bool *null_value, my_decimal *val)
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // Impossible
break;
}
@ -5125,7 +5107,6 @@ Item_func_set_user_var::check(bool use_result_field)
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
break;
}
@ -5160,7 +5141,6 @@ void Item_func_set_user_var::save_item_result(Item *item)
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
break;
}
@ -5228,7 +5208,6 @@ Item_func_set_user_var::update()
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
break;
}
@ -5684,7 +5663,6 @@ void Item_func_get_user_var::fix_length_and_dec()
break;
case ROW_RESULT: // Keep compiler happy
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0); // This case should never be chosen
break;
}

View file

@ -348,7 +348,7 @@ public:
are never equal is allowed in the arguments of a function.
This is overruled for the direct arguments of comparison functions.
*/
Item_args::propagate_equal_fields(thd, IDENTITY_SUBST, cond);
Item_args::propagate_equal_fields(thd, Context_identity(), cond);
return this;
}

View file

@ -526,7 +526,6 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table,
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
return 0;
@ -1202,7 +1201,6 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
};
setup_hybrid(thd, args[0], NULL);
@ -1380,7 +1378,6 @@ void Item_sum_sum::fix_length_and_dec()
break;
}
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: %s (%d, %d)",
@ -1871,7 +1868,6 @@ void Item_sum_variance::fix_length_and_dec()
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals));
@ -2314,7 +2310,6 @@ void Item_sum_hybrid::reset_field()
}
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);
}
}

View file

@ -3395,7 +3395,6 @@ int select_max_min_finder_subselect::send_data(List<Item> &items)
break;
case ROW_RESULT:
case TIME_RESULT:
case IMPOSSIBLE_RESULT:
// This case should never be choosen
DBUG_ASSERT(0);
op= 0;

View file

@ -12762,7 +12762,7 @@ static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
{
Item_func_eq *eq_item;
if (!(eq_item= new (thd->mem_root) Item_func_eq(thd, left_item, right_item)) ||
eq_item->set_cmp_func_and_arg_cmp_context())
eq_item->set_cmp_func())
return FALSE;
eq_item->quick_fix_field();
eq_list->push_back(eq_item, thd->mem_root);
@ -13096,7 +13096,7 @@ COND *Item_func::build_equal_items(THD *thd, COND_EQUAL *inherited,
as soon the field is not of a string type or the field reference is
an argument of a comparison predicate.
*/
COND *cond= propagate_equal_fields(thd, ANY_SUBST, inherited);
COND *cond= propagate_equal_fields(thd, Context_boolean(), inherited);
cond->update_used_tables();
DBUG_ASSERT(cond == this);
DBUG_ASSERT(!cond_equal_ref || !cond_equal_ref[0]);
@ -13875,9 +13875,9 @@ can_change_cond_ref_to_const(Item_bool_func2 *target,
{
if (!target_expr->eq(source_expr,0) ||
target_value == source_const ||
target_expr->cmp_context != source_expr->cmp_context)
target->compare_type() != source->compare_type())
return false;
if (target_expr->cmp_context == STRING_RESULT)
if (target->compare_type() == STRING_RESULT)
{
/*
In this example:
@ -14921,7 +14921,8 @@ void propagate_new_equalities(THD *thd, Item *cond,
}
else
{
cond= cond->propagate_equal_fields(thd, Item::ANY_SUBST, inherited);
cond= cond->propagate_equal_fields(thd,
Item::Context_boolean(), inherited);
cond->update_used_tables();
}
}

View file

@ -129,7 +129,6 @@ static my_bool CalcLen(UDF_ARGS *args, my_bool obj,
break;
case TIME_RESULT:
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
default:
// What should we do here ?
break;
@ -167,7 +166,6 @@ static my_bool CalcLen(UDF_ARGS *args, my_bool obj,
break;
case TIME_RESULT:
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
default:
// What should we do here ?
break;
@ -271,7 +269,6 @@ static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, int i)
break;
case TIME_RESULT:
case ROW_RESULT:
case IMPOSSIBLE_RESULT:
default:
break;
} // endswitch arg_type

View file

@ -590,8 +590,8 @@ DECLARE_THREAD(buf_dump_thread)(
srv_buf_dump_thread_active = TRUE;
buf_dump_status(STATUS_INFO, "not started");
buf_load_status(STATUS_INFO, "not started");
buf_dump_status(STATUS_INFO, "Dumping buffer pool(s) not yet started");
buf_load_status(STATUS_INFO, "Loading buffer pool(s) not yet started");
if (srv_buffer_pool_load_at_startup) {
buf_load();

View file

@ -590,8 +590,8 @@ DECLARE_THREAD(buf_dump_thread)(
srv_buf_dump_thread_active = TRUE;
buf_dump_status(STATUS_INFO, "not started");
buf_load_status(STATUS_INFO, "not started");
buf_dump_status(STATUS_INFO, "Dumping buffer pool(s) not yet started");
buf_load_status(STATUS_INFO, "Loading buffer pool(s) not yet started");
if (srv_buffer_pool_load_at_startup) {
buf_load();