mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Merge branch '10.1' of https://github.com/MariaDB/server into ok-debpkg-10.1
This commit is contained in:
commit
f8754d652e
45 changed files with 2199 additions and 336 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
64
mysql-test/include/equal_fields_propagation_datetime.inc
Normal file
64
mysql-test/include/equal_fields_propagation_datetime.inc
Normal 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;
|
||||
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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 #
|
||||
|
|
247
sql/field.cc
247
sql/field.cc
|
@ -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(<ime, 0) :
|
||||
const_item->get_date(<ime, 0))
|
||||
return NULL;
|
||||
return new (thd->mem_root) Item_datetime_literal(thd, <ime,
|
||||
decimals());
|
||||
}
|
||||
break;
|
||||
case ANY_SUBST:
|
||||
break;
|
||||
}
|
||||
return const_item;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** time type
|
||||
** In string context: HH:MM:SS
|
||||
|
@ -5635,6 +5833,29 @@ int Field_time::store_decimal(const my_decimal *d)
|
|||
return store_TIME_with_warning(<ime, &str, was_cut, have_smth_to_conv);
|
||||
}
|
||||
|
||||
|
||||
Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
|
||||
Item_field *field_item,
|
||||
Item *const_item)
|
||||
{
|
||||
switch (ctx.subst_constraint()) {
|
||||
case IDENTITY_SUBST:
|
||||
if (const_item->field_type() != MYSQL_TYPE_TIME ||
|
||||
const_item->decimals != decimals())
|
||||
{
|
||||
MYSQL_TIME ltime;
|
||||
if (const_item->get_date(<ime, TIME_TIME_ONLY))
|
||||
return NULL;
|
||||
return new (thd->mem_root) Item_time_literal(thd, <ime, decimals());
|
||||
}
|
||||
break;
|
||||
case ANY_SUBST:
|
||||
break;
|
||||
}
|
||||
return const_item;
|
||||
}
|
||||
|
||||
|
||||
uint32 Field_time_hires::pack_length() const
|
||||
{
|
||||
return time_hires_bytes[dec];
|
||||
|
@ -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(<ime, 0) :
|
||||
const_item->get_date(<ime, 0))
|
||||
return NULL;
|
||||
return new (thd->mem_root) Item_date_literal(thd, <ime);
|
||||
}
|
||||
break;
|
||||
case ANY_SUBST:
|
||||
break;
|
||||
}
|
||||
return const_item;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** datetime type
|
||||
** In string context: YYYY-MM-DD HH:MM:DD
|
||||
|
@ -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;
|
||||
|
|
120
sql/field.h
120
sql/field.h
|
@ -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); }
|
||||
};
|
||||
|
||||
|
|
162
sql/item.cc
162
sql/item.cc
|
@ -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;
|
||||
}
|
||||
|
|
58
sql/item.h
58
sql/item.h
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue