diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result index 5a02ca22392..b0859cafa6d 100644 --- a/mysql-test/r/case.result +++ b/mysql-test/r/case.result @@ -379,3 +379,63 @@ DROP TABLE t1; # # End of 10.1 test # +# +# Start of 10.3 tests +# +# +# MDEV-11554 Wrong result for CASE on a mixture of signed and unsigned expressions +# +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT +CASE -1 +WHEN -9223372036854775808 THEN 'one' + WHEN 18446744073709551615 THEN 'two' + END AS c; +c +NULL +PREPARE stmt FROM "SELECT + CASE -1 + WHEN -9223372036854775808 THEN 'one' + WHEN 18446744073709551615 THEN 'two' + END AS c"; +EXECUTE stmt; +c +NULL +EXECUTE stmt; +c +NULL +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +# +# MDEV-11555 CASE with a mixture of TIME and DATETIME returns a wrong result +# +SELECT +CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + END AS good, +CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + WHEN TIMESTAMP'2001-01-01 10:20:32' THEN 'three' + END AS was_bad_now_good; +good was_bad_now_good +one one +PREPARE stmt FROM "SELECT + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + END AS good, + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + WHEN TIMESTAMP'2001-01-01 10:20:32' THEN 'three' + END AS was_bad_now_good"; +EXECUTE stmt; +good was_bad_now_good +one one +EXECUTE stmt; +good was_bad_now_good +one one +DEALLOCATE PREPARE stmt; diff --git a/mysql-test/r/func_debug.result b/mysql-test/r/func_debug.result index 63319fd691e..90f9e4ddc32 100644 --- a/mysql-test/r/func_debug.result +++ b/mysql-test/r/func_debug.result @@ -1,270 +1,475 @@ SET SESSION debug_dbug="+d,Item_func_in"; +SET SESSION debug_dbug="+d,Predicant_to_list_comparator"; # Constant predicant, compatible types, bisect SELECT 1 IN (1,2); 1 IN (1,2) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1 IN (1,2,NULL); 1 IN (1,2,NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1 NOT IN (1,2); 1 NOT IN (1,2) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1 NOT IN (1,2,NULL); 1 NOT IN (1,2,NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1.0 IN (1.0,2.0); 1.0 IN (1.0,2.0) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1.0 IN (1.0,2.0,NULL); 1.0 IN (1.0,2.0,NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1.0 NOT IN (1.0,2.0); 1.0 NOT IN (1.0,2.0) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1.0 NOT IN (1.0,2.0,NULL); 1.0 NOT IN (1.0,2.0,NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1e0 IN (1e0,2e0); 1e0 IN (1e0,2e0) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1e0 IN (1e0,2e0,NULL); 1e0 IN (1e0,2e0,NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1e0 NOT IN (1e0,2e0); 1e0 NOT IN (1e0,2e0) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1e0 NOT IN (1e0,2e0,NULL); 1e0 NOT IN (1e0,2e0,NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 'a' IN ('a','b'); 'a' IN ('a','b') 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 'a' IN ('a','b',NULL); 'a' IN ('a','b',NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 'a' NOT IN ('a','b'); 'a' NOT IN ('a','b') 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 'a' NOT IN ('a','b',NULL); 'a' NOT IN ('a','b',NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30'); TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL); TIMESTAMP'2001-01-01 10:20:30' IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30'); TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30') 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL); TIMESTAMP'2001-01-01 10:20:30' NOT IN ('2001-01-01 10:20:30','2001-02-02 10:20:30',NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIME'10:20:30' IN ('10:20:30','10:20:30'); TIME'10:20:30' IN ('10:20:30','10:20:30') 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIME'10:20:30' IN ('10:20:30','10:20:30',NULL); TIME'10:20:30' IN ('10:20:30','10:20:30',NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIME'10:20:30' NOT IN ('10:20:30','10:20:30'); TIME'10:20:30' NOT IN ('10:20:30','10:20:30') 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT TIME'10:20:30' NOT IN ('10:20:30','10:20:30',NULL); TIME'10:20:30' NOT IN ('10:20:30','10:20:30',NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02'); DATE'2001-01-01' IN ('2001-01-01','2001-02-02') 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL); DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02'); DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02') 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL); DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes # Column predicant, compatible types, bisect +CREATE TABLE t1 (a INT UNSIGNED); +SELECT a IN (1.0, 1) FROM t1; +a IN (1.0, 1) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +DROP TABLE t1; CREATE TABLE t1 (a INT); SELECT a IN (1,2,3) FROM t1; a IN (1,2,3) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN (1,2,3,NULL) FROM t1; a IN (1,2,3,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT a IN (1.0, CAST(1 AS UNSIGNED)) FROM t1; +a IN (1.0, CAST(1 AS UNSIGNED)) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT a IN (1.0, CAST(1 AS UNSIGNED),NULL) FROM t1; +a IN (1.0, CAST(1 AS UNSIGNED),NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN (1,2,3) FROM t1; a NOT IN (1,2,3) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN (1,2,3,NULL) FROM t1; a NOT IN (1,2,3,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT a NOT IN (1.0, CAST(1 AS UNSIGNED)) FROM t1; +a NOT IN (1.0, CAST(1 AS UNSIGNED)) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT a NOT IN (1.0, CAST(1 AS UNSIGNED),NULL) FROM t1; +a NOT IN (1.0, CAST(1 AS UNSIGNED),NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a DOUBLE); SELECT a IN (1e0,2,3.0) FROM t1; a IN (1e0,2,3.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN (1e0,2,3.0,NULL) FROM t1; a IN (1e0,2,3.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN (1e0,2,3.0) FROM t1; a NOT IN (1e0,2,3.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN (1e0,2,3.0,NULL) FROM t1; a NOT IN (1e0,2,3.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(10,1)); SELECT a IN (1,2.0,3.0) FROM t1; a IN (1,2.0,3.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN (1,2.0,3.0,NULL) FROM t1; a IN (1,2.0,3.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN (1,2.0,3.0) FROM t1; a NOT IN (1,2.0,3.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN (1,2.0,3.0,NULL) FROM t1; a NOT IN (1,2.0,3.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(10)); SELECT a IN ('a','b','c') FROM t1; a IN ('a','b','c') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN ('a','b','c',NULL) FROM t1; a IN ('a','b','c',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('a','b','c') FROM t1; a NOT IN ('a','b','c') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('a','b','c',NULL) FROM t1; a NOT IN ('a','b','c',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a DATE); SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1; a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1; a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a TIME); SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) FROM t1; a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) FROM t1; a IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) FROM t1; a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) FROM t1; a NOT IN ('10:20:30',TIME'10:20:30',102030,102030.0,102030e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a DATETIME); SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) FROM t1; a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 +Note 1105 DBUG: [5] arg=6 handler=0 +Note 1105 DBUG: [6] arg=7 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) FROM t1; a IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 +Note 1105 DBUG: [5] arg=6 handler=0 +Note 1105 DBUG: [6] arg=7 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) FROM t1; a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 +Note 1105 DBUG: [5] arg=6 handler=0 +Note 1105 DBUG: [6] arg=7 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) FROM t1; a NOT IN ('2001-01-01',TIMESTAMP'2001-01-01 10:20:30',DATE'2001-01-01',TIME'10:20:30',20010101102030,20010101102030.0,20010101102030e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 +Note 1105 DBUG: [4] arg=5 handler=0 +Note 1105 DBUG: [5] arg=6 handler=0 +Note 1105 DBUG: [6] arg=7 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; # Constant predicant, compatible types, no bisect @@ -273,126 +478,210 @@ CREATE TABLE t1 (a INT); SELECT 1 IN (a,1,2,3) FROM t1; 1 IN (a,1,2,3) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 IN (a,1,2,3,NULL) FROM t1; 1 IN (a,1,2,3,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 NOT IN (a,1,2,3) FROM t1; 1 NOT IN (a,1,2,3) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 NOT IN (a,1,2,3,NULL) FROM t1; 1 NOT IN (a,1,2,3,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a DOUBLE); SELECT 1 IN (a,1e0,2e0,3e0) FROM t1; 1 IN (a,1e0,2e0,3e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 IN (a,1e0,2e0,3e0,NULL) FROM t1; 1 IN (a,1e0,2e0,3e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 NOT IN (a,1e0,2e0,3e0) FROM t1; 1 NOT IN (a,1e0,2e0,3e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 NOT IN (a,1e0,2e0,3e0,NULL) FROM t1; 1 NOT IN (a,1e0,2e0,3e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(10,1)); SELECT 1 IN (a,1.0,2.0,3.0) FROM t1; 1 IN (a,1.0,2.0,3.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 IN (a,1.0,2.0,3.0,NULL) FROM t1; 1 IN (a,1.0,2.0,3.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 NOT IN (a,1.0,2.0,3.0) FROM t1; 1 NOT IN (a,1.0,2.0,3.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 NOT IN (a,1.0,2.0,3.0,NULL) FROM t1; 1 NOT IN (a,1.0,2.0,3.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(10)); SELECT 'a' IN (a,'b','c') FROM t1; 'a' IN (a,'b','c') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 'a' IN (a,'b','c',NULL) FROM t1; 'a' IN (a,'b','c',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 'a' NOT IN (a,'b','c') FROM t1; 'a' NOT IN (a,'b','c') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 'a' NOT IN (a,'b','c',NULL) FROM t1; 'a' NOT IN (a,'b','c',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a DATE); SELECT DATE'2001-01-01' IN (a,'2001-01-01') FROM t1; DATE'2001-01-01' IN (a,'2001-01-01') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT DATE'2001-01-01' IN (a,'2001-01-01',NULL) FROM t1; DATE'2001-01-01' IN (a,'2001-01-01',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01') FROM t1; DATE'2001-01-01' NOT IN (a,'2001-01-01') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL) FROM t1; DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a TIME); SELECT TIME'10:20:30' IN (a,'10:20:30') FROM t1; TIME'10:20:30' IN (a,'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT TIME'10:20:30' IN (a,'10:20:30',NULL) FROM t1; TIME'10:20:30' IN (a,'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT TIME'10:20:30' NOT IN (a,'10:20:30') FROM t1; TIME'10:20:30' NOT IN (a,'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT TIME'10:20:30' NOT IN (a,'10:20:30',NULL) FROM t1; TIME'10:20:30' NOT IN (a,'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a DATETIME); SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30') FROM t1; TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; TIMESTAMP'2001-01-01 10:20:30' IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30') FROM t1; TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; TIMESTAMP'2001-01-01 10:20:30' NOT IN (a,TIMESTAMP'2001-01-01 10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; # Constant predicant, incompatible types, no bisect @@ -400,265 +689,595 @@ SELECT 1 IN (1,2e0); 1 IN (1,2e0) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1 IN (1,2e0,NULL); 1 IN (1,2e0,NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1 NOT IN (1,2e0); 1 NOT IN (1,2e0) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1 NOT IN (1,2e0,NULL); 1 NOT IN (1,2e0,NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1.0 IN (1.0,2e0); 1.0 IN (1.0,2e0) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1.0 IN (1.0,2e0,NULL); 1.0 IN (1.0,2e0,NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1.0 NOT IN (1.0,2e0); 1.0 NOT IN (1.0,2e0) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1.0 NOT IN (1.0,2e0,NULL); 1.0 NOT IN (1.0,2e0,NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1e0 IN (1.0,TIME'10:20:30'); 1e0 IN (1.0,TIME'10:20:30') 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1e0 IN (1.0,TIME'10:20:30',NULL); 1e0 IN (1.0,TIME'10:20:30',NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1e0 NOT IN (1.0,TIME'10:20:30'); 1e0 NOT IN (1.0,TIME'10:20:30') 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 1e0 NOT IN (1.0,TIME'10:20:30',NULL); 1e0 NOT IN (1.0,TIME'10:20:30',NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 'a' IN ('a',2); 'a' IN ('a',2) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 'a' IN ('a',2,NULL); 'a' IN ('a',2,NULL) 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 'a' NOT IN ('a',2); 'a' NOT IN ('a',2) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT 'a' NOT IN ('a',2,NULL); 'a' NOT IN ('a',2,NULL) 0 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' IN (1,TIME'10:20:30'); +TIME'10:20:30' IN (1,TIME'10:20:30') +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT TIME'10:20:30' IN (1,TIME'10:20:30',NULL); +TIME'10:20:30' IN (1,TIME'10:20:30',NULL) +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30'); +TIME'10:20:30' NOT IN (1,TIME'10:20:30') +0 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL); +TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL) +0 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +0 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +0 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +0 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +0 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 Note 1105 DBUG: types_compatible=no bisect=no # Column predicant, incompatible types, no bisect CREATE TABLE t1 (a INT); SELECT a IN (1,1e0) FROM t1; a IN (1,1e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,1e0,NULL) FROM t1; a IN (1,1e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; +a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; +a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,1e0) FROM t1; a NOT IN (1,1e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,1e0,NULL) FROM t1; a NOT IN (1,1e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; +a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; +a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: [2] arg=3 handler=0 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,1.0) FROM t1; a IN (1,1.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,1.0,NULL) FROM t1; a IN (1,1.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,1.0) FROM t1; a NOT IN (1,1.0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,1.0,NULL) FROM t1; a NOT IN (1,1.0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,'1') FROM t1; a IN (1,'1') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,'1',NULL) FROM t1; a IN (1,'1',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,'1') FROM t1; a NOT IN (1,'1') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,'1',NULL) FROM t1; a NOT IN (1,'1',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIME'10:20:30') FROM t1; a IN (1,TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIME'10:20:30',NULL) FROM t1; a IN (1,TIME'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIME'10:20:30') FROM t1; a NOT IN (1,TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIME'10:20:30',NULL) FROM t1; a NOT IN (1,TIME'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(10,0)); SELECT a IN (1,1e0) FROM t1; a IN (1,1e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,1e0,NULL) FROM t1; a IN (1,1e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,1e0) FROM t1; a NOT IN (1,1e0) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,1e0,NULL) FROM t1; a NOT IN (1,1e0,NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,'1') FROM t1; a IN (1,'1') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,'1',NULL) FROM t1; a IN (1,'1',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,'1') FROM t1; a NOT IN (1,'1') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,'1',NULL) FROM t1; a NOT IN (1,'1',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIME'10:20:30') FROM t1; a IN (1,TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIME'10:20:30',NULL) FROM t1; a IN (1,TIME'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIME'10:20:30') FROM t1; a NOT IN (1,TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIME'10:20:30',NULL) FROM t1; a NOT IN (1,TIME'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no DROP TABLE t1; CREATE TABLE t1 (a DOUBLE); SELECT a IN (1,TIME'10:20:30') FROM t1; a IN (1,TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIME'10:20:30',NULL) FROM t1; a IN (1,TIME'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIME'10:20:30') FROM t1; a NOT IN (1,TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIME'10:20:30',NULL) FROM t1; a NOT IN (1,TIME'10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,DATE'2001-01-01') FROM t1; a IN (1,DATE'2001-01-01') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,DATE'2001-01-01',NULL) FROM t1; a IN (1,DATE'2001-01-01',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,DATE'2001-01-01') FROM t1; a NOT IN (1,DATE'2001-01-01') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,DATE'2001-01-01',NULL) FROM t1; a NOT IN (1,DATE'2001-01-01',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIMESTAMP'2001-01-01 10:20:30') FROM t1; a IN (1,TIMESTAMP'2001-01-01 10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN (1,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; a IN (1,TIMESTAMP'2001-01-01 10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIMESTAMP'2001-01-01 10:20:30') FROM t1; a NOT IN (1,TIMESTAMP'2001-01-01 10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN (1,TIMESTAMP'2001-01-01 10:20:30',NULL) FROM t1; a NOT IN (1,TIMESTAMP'2001-01-01 10:20:30',NULL) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(10)); SELECT a IN ('a',1) FROM t1; a IN ('a',1) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a IN ('a',TIME'10:20:30') FROM t1; a IN ('a',TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN ('a',1) FROM t1; a NOT IN ('a',1) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 Note 1105 DBUG: types_compatible=no bisect=no SELECT a NOT IN ('a',TIME'10:20:30') FROM t1; a NOT IN ('a',TIME'10:20:30') Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +DROP TABLE t1; +CREATE TABLE t1 (a TIME); +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=0 +Note 1105 DBUG: [3] arg=4 handler=3 Note 1105 DBUG: types_compatible=no bisect=no DROP TABLE t1; # Not top level, negated: cond3 is false @@ -666,40 +1285,56 @@ CREATE TABLE t1 (a INT); SELECT ROW(a,a) NOT IN ((1,1),(2,NULL)) FROM t1; ROW(a,a) NOT IN ((1,1),(2,NULL)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,a) NOT IN ((1,1),(2,2)) FROM t1; ROW(a,a) NOT IN ((1,1),(2,2)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL, b INT); SELECT ROW(a,a) NOT IN ((1,1),(2,NULL)) FROM t1; ROW(a,a) NOT IN ((1,1),(2,NULL)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,a) NOT IN ((1,1),(2,2)) FROM t1; ROW(a,a) NOT IN ((1,1),(2,2)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a INT); SELECT ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,NULL))) FROM t1; ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,NULL))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,2))) FROM t1; ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,2))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL); SELECT ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,NULL))) FROM t1; ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,NULL))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,2))) FROM t1; ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,2))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; # Not top level, not negated: cond3 is false @@ -707,40 +1342,56 @@ CREATE TABLE t1 (a INT); SELECT ROW(a,a) IN ((1,1),(2,NULL)) FROM t1; ROW(a,a) IN ((1,1),(2,NULL)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,a) IN ((1,1),(2,2)) FROM t1; ROW(a,a) IN ((1,1),(2,2)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL); SELECT ROW(a,a) IN ((1,1),(2,NULL)) FROM t1; ROW(a,a) IN ((1,1),(2,NULL)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,a) IN ((1,1),(2,2)) FROM t1; ROW(a,a) IN ((1,1),(2,2)) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a INT); SELECT ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL))) FROM t1; ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,2))) FROM t1; ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,2))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL); SELECT ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL))) FROM t1; ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,2))) FROM t1; ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,2))) Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; # Top level, negated: cond3 is false @@ -748,40 +1399,56 @@ CREATE TABLE t1 (a INT); SELECT 1 FROM t1 WHERE ROW(a,a) NOT IN ((1,1),(2,NULL)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 FROM t1 WHERE ROW(a,a) NOT IN ((1,1),(2,2)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL); SELECT 1 FROM t1 WHERE ROW(a,a) NOT IN ((1,1),(2,NULL)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 FROM t1 WHERE ROW(a,a) NOT IN ((1,1),(2,2)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a INT); SELECT 1 FROM t1 WHERE ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,NULL))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 FROM t1 WHERE ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,2))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL); SELECT 1 FROM t1 WHERE ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,NULL))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=no SELECT 1 FROM t1 WHERE ROW(a,(a,a)) NOT IN ((1,(1,1)),(2,(2,2))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; # Top level, not negated: cond3 is true @@ -789,40 +1456,202 @@ CREATE TABLE t1 (a INT); SELECT 1 FROM t1 WHERE ROW(a,a) IN ((1,1),(2,NULL)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1 FROM t1 WHERE ROW(a,a) IN ((1,1),(2,2)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL); SELECT 1 FROM t1 WHERE ROW(a,a) IN ((1,1),(2,NULL)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1 FROM t1 WHERE ROW(a,a) IN ((1,1),(2,2)); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a INT); SELECT 1 FROM t1 WHERE ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1 FROM t1 WHERE ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,2))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL); SELECT 1 FROM t1 WHERE ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes SELECT 1 FROM t1 WHERE ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,2))); 1 Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 Note 1105 DBUG: types_compatible=yes bisect=yes DROP TABLE t1; +# +# MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result +# +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); +TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +PREPARE stmt FROM "SELECT + TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32')"; +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +EXECUTE stmt; +TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +EXECUTE stmt; +TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +1 +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=3 handler=2 +Note 1105 DBUG: types_compatible=no bisect=no +DEALLOCATE PREPARE stmt; +CREATE TABLE t1 (a VARCHAR(10)); +INSERT INTO t1 VALUES ('A'),('B'),('A'); +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,'A'); +a b +A NULL +B NULL +Warnings: +Note 1105 DBUG: [0] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN ('A',b); +a b +A NULL +B NULL +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=yes +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,a); +a b +A NULL +Warnings: +Note 1105 DBUG: [0] arg=2 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=no +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (a,b); +a b +A NULL +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: types_compatible=yes bisect=no +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,'A',10); +a b +A NULL +B NULL +Warnings: +Note 1105 DBUG: [0] arg=2 handler=0 +Note 1105 DBUG: [1] arg=3 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN ('A',b,10); +a b +A NULL +B NULL +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=3 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,a,10); +a b +A NULL +Warnings: +Note 1105 DBUG: [0] arg=2 handler=0 +Note 1105 DBUG: [1] arg=3 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +Warning 1292 Truncated incorrect DOUBLE value: 'A' +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (a,b,10); +a b +A NULL +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=3 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +Warning 1292 Truncated incorrect DOUBLE value: 'A' +DROP TABLE t1; +# +# MDEV-11497 Wrong result for (int_expr IN (mixture of signed and unsigned expressions)) +# +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT * FROM t1 WHERE -1 IN (a,b); +a b +Warnings: +Note 1105 DBUG: [0] arg=1 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +Note 1105 DBUG: types_compatible=no bisect=no +DROP TABLE t1; +# +# MDEV-11554 Wrong result for CASE on a mixture of signed and unsigned expressions +# +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT +CASE -1 +WHEN -9223372036854775808 THEN 'one' + WHEN 18446744073709551615 THEN 'two' + END AS c; +c +NULL +Warnings: +Note 1105 DBUG: [0] arg=0 handler=0 +Note 1105 DBUG: [1] arg=2 handler=1 +DROP TABLE t1; +# +# MDEV-11555 CASE with a mixture of TIME and DATETIME returns a wrong result +# +SELECT +CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + END AS good, +CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + WHEN TIMESTAMP'2001-01-01 10:20:32' THEN 'three' + END AS was_bad_now_good; +good was_bad_now_good +one one +Warnings: +Note 1105 DBUG: [0] arg=0 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [0] arg=0 handler=0 +Note 1105 DBUG: [1] arg=2 handler=0 +Note 1105 DBUG: [2] arg=4 handler=2 +SET SESSION debug_dbug="-d,Predicant_to_list_comparator"; SET SESSION debug_dbug="-d,Item_func_in"; diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index aaf1d981e59..5e0b95beb2d 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -855,3 +855,34 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1 and `test`.`t1`.`a` in (1,2,'3') DROP TABLE t1; +# +# Start of 10.3 tests +# +# +# MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result +# +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); +TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +1 +PREPARE stmt FROM "SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32')"; +EXECUTE stmt; +TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +1 +EXECUTE stmt; +TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +1 +DEALLOCATE PREPARE stmt; +# +# MDEV-11497 Wrong result for (int_expr IN (mixture of signed and unsigned expressions)) +# +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT * FROM t1 WHERE -1 IN (a,b); +a b +PREPARE stmt FROM 'SELECT * FROM t1 WHERE -1 IN (a,b)'; +EXECUTE stmt; +a b +EXECUTE stmt; +a b +DEALLOCATE PREPARE stmt; +DROP TABLE t1; diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index ce1cb424a6c..2550a95a0c9 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -1246,3 +1246,25 @@ DROP TABLE t1,t2; # # End of 10.2 tests # +# +# Start of 10.3 tests +# +# +# MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result +# +SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:00'); +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31'); +TIME'10:20:30' IN (102030,TIME'10:20:31') +1 +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); +TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') +1 +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('10:20:30'),('10:20:31'),('10:20:32'); +SELECT a FROM t1 WHERE a IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') ORDER BY a; +a +10:20:30 +10:20:31 +10:20:32 +DROP TABLE t1; +SET timestamp=DEFAULT; diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index 7cc74c52b28..87f12cd9e38 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -275,3 +275,58 @@ DROP TABLE t1; --echo # --echo # End of 10.1 test --echo # + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-11554 Wrong result for CASE on a mixture of signed and unsigned expressions +--echo # + +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT + CASE -1 + WHEN -9223372036854775808 THEN 'one' + WHEN 18446744073709551615 THEN 'two' + END AS c; + +PREPARE stmt FROM "SELECT + CASE -1 + WHEN -9223372036854775808 THEN 'one' + WHEN 18446744073709551615 THEN 'two' + END AS c"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +DROP TABLE t1; + +--echo # +--echo # MDEV-11555 CASE with a mixture of TIME and DATETIME returns a wrong result +--echo # +SELECT + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + END AS good, + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + WHEN TIMESTAMP'2001-01-01 10:20:32' THEN 'three' + END AS was_bad_now_good; + +PREPARE stmt FROM "SELECT + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + END AS good, + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + WHEN TIMESTAMP'2001-01-01 10:20:32' THEN 'three' + END AS was_bad_now_good"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; diff --git a/mysql-test/t/func_debug.test b/mysql-test/t/func_debug.test index 10eec49b5ab..e0960f736cb 100644 --- a/mysql-test/t/func_debug.test +++ b/mysql-test/t/func_debug.test @@ -1,6 +1,7 @@ --source include/have_debug.inc SET SESSION debug_dbug="+d,Item_func_in"; +SET SESSION debug_dbug="+d,Predicant_to_list_comparator"; --echo # Constant predicant, compatible types, bisect SELECT 1 IN (1,2); @@ -41,11 +42,22 @@ SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL); --echo # Column predicant, compatible types, bisect +# Special case: mixture of unsigned, signed and decimal +CREATE TABLE t1 (a INT UNSIGNED); +# a=1.0 is done as decimal, because decimal bits int +# a=1 is done as decimal as well, because of different unsigned flag +SELECT a IN (1.0, 1) FROM t1; +DROP TABLE t1; + CREATE TABLE t1 (a INT); SELECT a IN (1,2,3) FROM t1; SELECT a IN (1,2,3,NULL) FROM t1; +SELECT a IN (1.0, CAST(1 AS UNSIGNED)) FROM t1; +SELECT a IN (1.0, CAST(1 AS UNSIGNED),NULL) FROM t1; SELECT a NOT IN (1,2,3) FROM t1; SELECT a NOT IN (1,2,3,NULL) FROM t1; +SELECT a NOT IN (1.0, CAST(1 AS UNSIGNED)) FROM t1; +SELECT a NOT IN (1.0, CAST(1 AS UNSIGNED),NULL) FROM t1; DROP TABLE t1; CREATE TABLE t1 (a DOUBLE); @@ -163,12 +175,33 @@ SELECT 'a' IN ('a',2,NULL); SELECT 'a' NOT IN ('a',2); SELECT 'a' NOT IN ('a',2,NULL); +SELECT TIME'10:20:30' IN (1,TIME'10:20:30'); +SELECT TIME'10:20:30' IN (1,TIME'10:20:30',NULL); +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +SELECT TIME'10:20:30' IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +SELECT TIME'10:20:30' IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30'); +SELECT TIME'10:20:30' NOT IN (1,TIME'10:20:30',NULL); +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +SELECT TIME'10:20:30' NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32'); +SELECT TIME'10:20:30' NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL); + --echo # Column predicant, incompatible types, no bisect CREATE TABLE t1 (a INT); SELECT a IN (1,1e0) FROM t1; SELECT a IN (1,1e0,NULL) FROM t1; +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +SELECT a IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +SELECT a IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; SELECT a NOT IN (1,1e0) FROM t1; SELECT a NOT IN (1,1e0,NULL) FROM t1; +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +SELECT a NOT IN (CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED)) FROM t1; +SELECT a NOT IN (CAST(1 AS DECIMAL),CAST(1 AS SIGNED), CAST(1 AS UNSIGNED),NULL) FROM t1; SELECT a IN (1,1.0) FROM t1; SELECT a IN (1,1.0,NULL) FROM t1; @@ -227,6 +260,17 @@ SELECT a NOT IN ('a',1) FROM t1; SELECT a NOT IN ('a',TIME'10:20:30') FROM t1; DROP TABLE t1; +CREATE TABLE t1 (a TIME); +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +SELECT a IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +SELECT a IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +SELECT a NOT IN (102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32') FROM t1; +SELECT a NOT IN (102030, 102030, TIME'10:20:30',TIMESTAMP'2001-01-01 10:20:32',NULL) FROM t1; +DROP TABLE t1; + # # ROW tests # @@ -366,5 +410,68 @@ SELECT 1 FROM t1 WHERE ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,NULL))); SELECT 1 FROM t1 WHERE ROW(a,(a,a)) IN ((1,(1,1)),(2,(2,2))); DROP TABLE t1; +--echo # +--echo # MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result +--echo # +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); + +PREPARE stmt FROM "SELECT + TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32')"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +CREATE TABLE t1 (a VARCHAR(10)); +INSERT INTO t1 VALUES ('A'),('B'),('A'); +# Compatible types +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,'A'); +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN ('A',b); +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,a); +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (a,b); +# Incompatible types +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,'A',10); +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN ('A',b,10); +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,a,10); +SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (a,b,10); +DROP TABLE t1; + +--echo # +--echo # MDEV-11497 Wrong result for (int_expr IN (mixture of signed and unsigned expressions)) +--echo # +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT * FROM t1 WHERE -1 IN (a,b); +DROP TABLE t1; + + +--echo # +--echo # MDEV-11554 Wrong result for CASE on a mixture of signed and unsigned expressions +--echo # + +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT + CASE -1 + WHEN -9223372036854775808 THEN 'one' + WHEN 18446744073709551615 THEN 'two' + END AS c; +DROP TABLE t1; + +--echo # +--echo # MDEV-11555 CASE with a mixture of TIME and DATETIME returns a wrong result +--echo # +SELECT + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + END AS good, + CASE TIME'10:20:30' + WHEN 102030 THEN 'one' + WHEN TIME'10:20:31' THEN 'two' + WHEN TIMESTAMP'2001-01-01 10:20:32' THEN 'three' + END AS was_bad_now_good; + + +SET SESSION debug_dbug="-d,Predicant_to_list_comparator"; SET SESSION debug_dbug="-d,Item_func_in"; diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 9e848aa1847..a7db3879cce 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -641,3 +641,29 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=1 AND 1 IN (1,a,'3'); --echo # Not Ok to propagate equalities into the left IN argument in case of multiple comparison types EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=1 AND a IN (1,2,'3'); DROP TABLE t1; + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result +--echo # + +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); +PREPARE stmt FROM "SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32')"; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +--echo # +--echo # MDEV-11497 Wrong result for (int_expr IN (mixture of signed and unsigned expressions)) +--echo # +CREATE TABLE t1 (a BIGINT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (-9223372036854775808,18446744073709551615); +SELECT * FROM t1 WHERE -1 IN (a,b); +PREPARE stmt FROM 'SELECT * FROM t1 WHERE -1 IN (a,b)'; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index c4b93d6dbb2..af4e3289df8 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -748,3 +748,19 @@ DROP TABLE t1,t2; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-11514 IN with a mixture of TIME and DATETIME returns a wrong result +--echo # +SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:00'); +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31'); +SELECT TIME'10:20:30' IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32'); +CREATE TABLE t1 (a TIME); +INSERT INTO t1 VALUES ('10:20:30'),('10:20:31'),('10:20:32'); +SELECT a FROM t1 WHERE a IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') ORDER BY a; +DROP TABLE t1; +SET timestamp=DEFAULT; diff --git a/sql/item.h b/sql/item.h index cf915f74a5e..ed7d07eaf54 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1280,11 +1280,6 @@ public: return MYSQL_TYPE_DATETIME; } } - // Get a temporal value to compare to another Item - longlong val_temporal_packed(const Item *other) - { - return val_temporal_packed(field_type_for_temporal_comparison(other)); - } bool get_seconds(ulonglong *sec, ulong *sec_part); virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date(ltime,fuzzydate); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b18bf1d9dd7..a81dd4694a9 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -122,11 +122,18 @@ bool Type_handler_hybrid_field_type::aggregate_for_comparison(Item **items, uint nitems) { uint unsigned_count= items[0]->unsigned_flag; - set_handler(items[0]->type_handler()); + /* + Convert sub-type to super-type (e.g. DATE to DATETIME, INT to BIGINT, etc). + Otherwise Predicant_to_list_comparator will treat sub-types of the same + super-type as different data types and won't be able to use bisection in + many cases. + */ + set_handler(items[0]->type_handler()->type_handler_for_comparison()); for (uint i= 1 ; i < nitems ; i++) { unsigned_count+= items[i]->unsigned_flag; - aggregate_for_comparison(items[i]->type_handler()); + aggregate_for_comparison(items[i]->type_handler()-> + type_handler_for_comparison()); /* When aggregating types of two row expressions we have to check that they have the same cardinality and that each component @@ -2864,8 +2871,10 @@ Item_func_nullif::is_null() Item_func_case::Item_func_case(THD *thd, List &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), m_found_types(0) + Item_func_hybrid_field_type(thd), + Predicant_to_list_comparator(thd, list.elements/*QQ*/), + first_expr_num(-1), else_expr_num(-1), + left_cmp_type(INT_RESULT), m_found_types(0) { ncases= list.elements; if (first_expr_arg) @@ -2879,7 +2888,6 @@ Item_func_case::Item_func_case(THD *thd, List &list, list.push_back(else_expr_arg, thd->mem_root); } set_arguments(thd, list); - bzero(&cmp_items, sizeof(cmp_items)); } /** @@ -2905,8 +2913,6 @@ Item_func_case::Item_func_case(THD *thd, List &list, Item *Item_func_case::find_item(String *str) { - uint value_added_map= 0; - if (first_expr_num == -1) { for (uint i=0 ; i < ncases ; i+=2) @@ -2920,23 +2926,9 @@ Item *Item_func_case::find_item(String *str) else { /* Compare every WHEN argument with it and return the first match */ - for (uint i=0 ; i < ncases ; i+=2) - { - if (args[i]->real_item()->type() == NULL_ITEM) - continue; - cmp_type= item_cmp_type(left_cmp_type, args[i]); - DBUG_ASSERT(cmp_type != ROW_RESULT); - DBUG_ASSERT(cmp_items[(uint)cmp_type]); - if (!(value_added_map & (1U << (uint)cmp_type))) - { - cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]); - if ((null_value=args[first_expr_num]->null_value)) - return else_expr_num != -1 ? args[else_expr_num] : 0; - value_added_map|= 1U << (uint)cmp_type; - } - if (cmp_items[(uint)cmp_type]->cmp(args[i]) == FALSE) - return args[i + 1]; - } + uint idx; + if (!Predicant_to_list_comparator::cmp(this, &idx, NULL)) + return args[idx + 1]; } // No, WHEN clauses all missed, return ELSE expression return else_expr_num != -1 ? args[else_expr_num] : 0; @@ -3074,6 +3066,25 @@ static void change_item_tree_if_needed(THD *thd, } +bool Item_func_case::prepare_predicant_and_values(THD *thd, uint *found_types) +{ + bool have_null= false; + uint type_cnt; + Type_handler_hybrid_field_type tmp; + add_predicant(this, (uint) first_expr_num); + for (uint i= 0 ; i < ncases / 2; i++) + { + if (add_value_skip_null(this, i * 2, &have_null)) + return true; + } + all_values_added(&tmp, &type_cnt, &m_found_types); +#ifndef DBUG_OFF + Predicant_to_list_comparator::debug_print(thd); +#endif + return false; +} + + void Item_func_case::fix_length_and_dec() { Item **agg= arg_buffer; @@ -3122,7 +3133,17 @@ void Item_func_case::fix_length_and_dec() */ if (first_expr_num != -1) { - uint i; + if (prepare_predicant_and_values(thd, &m_found_types)) + { + /* + If Predicant_to_list_comparator() fails to prepare components, + it must put an error into the diagnostics area. This is needed + to make fix_fields() catches such errors. + */ + DBUG_ASSERT(thd->is_error()); + return; + } + agg[0]= args[first_expr_num]; left_cmp_type= agg[0]->cmp_type(); @@ -3138,10 +3159,6 @@ void Item_func_case::fix_length_and_dec() if (!(m_found_types= collect_cmp_types(agg, nagg))) return; - Item *date_arg= 0; - if (m_found_types & (1U << TIME_RESULT)) - date_arg= find_date_time_item(args, arg_count, 0); - if (m_found_types & (1U << STRING_RESULT)) { /* @@ -3179,20 +3196,11 @@ void Item_func_case::fix_length_and_dec() for (nagg= 0; nagg < ncases / 2; nagg++) change_item_tree_if_needed(thd, &args[nagg * 2], agg[nagg + 1]); + } - for (i= 0; i <= (uint)TIME_RESULT; i++) - { - if (m_found_types & (1U << i) && !cmp_items[i]) - { - DBUG_ASSERT((Item_result)i != ROW_RESULT); - - if (!(cmp_items[i]= - cmp_item::get_comparator((Item_result)i, date_arg, - cmp_collation.collation))) - return; - } - } + if (make_unique_cmp_items(thd, cmp_collation.collation)) + return; } } @@ -3323,20 +3331,6 @@ void Item_func_case::print(String *str, enum_query_type query_type) } -void Item_func_case::cleanup() -{ - uint i; - DBUG_ENTER("Item_func_case::cleanup"); - Item_func::cleanup(); - for (i= 0; i <= (uint)TIME_RESULT; i++) - { - delete cmp_items[i]; - cmp_items[i]= 0; - } - DBUG_VOID_RETURN; -} - - /** Coalesce - return first not NULL argument. */ @@ -3788,6 +3782,93 @@ Item *in_decimal::create_item(THD *thd) } +bool Predicant_to_list_comparator::alloc_comparators(THD *thd, uint nargs) +{ + size_t nbytes= sizeof(Predicant_to_value_comparator) * nargs; + if (!(m_comparators= (Predicant_to_value_comparator *) thd->alloc(nbytes))) + return true; + memset(m_comparators, 0, nbytes); + return false; +} + + +bool Predicant_to_list_comparator::add_value(Item_args *args, + uint value_index) +{ + DBUG_ASSERT(m_predicant_index < args->argument_count()); + DBUG_ASSERT(value_index < args->argument_count()); + Type_handler_hybrid_field_type tmp; + Item *tmpargs[2]; + tmpargs[0]= args->arguments()[m_predicant_index]; + tmpargs[1]= args->arguments()[value_index]; + if (tmp.aggregate_for_comparison(tmpargs, 2)) + return true; + m_comparators[m_comparator_count].m_handler= tmp.type_handler(); + m_comparators[m_comparator_count].m_arg_index= value_index; + m_comparator_count++; + return false; +} + + +bool Predicant_to_list_comparator::add_value_skip_null(Item_args *args, + uint value_index, + bool *nulls_found) +{ + /* + Skip explicit NULL constant items. + Using real_item() to correctly detect references to explicit NULLs + in HAVING clause, e.g. in this example "b" is skipped: + SELECT a,NULL AS b FROM t1 GROUP BY a HAVING 'A' IN (b,'A'); + */ + if (args->arguments()[value_index]->real_item()->type() == Item::NULL_ITEM) + { + *nulls_found= true; + return false; + } + return add_value(args, value_index); +} + + +void Predicant_to_list_comparator:: + detect_unique_handlers(Type_handler_hybrid_field_type *compatible, + uint *unique_count, + uint *found_types) +{ + *unique_count= 0; + *found_types= 0; + for (uint i= 0; i < m_comparator_count; i++) + { + uint idx; + if (find_handler(&idx, m_comparators[i].m_handler, i)) + { + m_comparators[i].m_handler_index= i; // New unique handler + (*unique_count)++; + (*found_types)|= 1U << m_comparators[i].m_handler->cmp_type(); + compatible->set_handler(m_comparators[i].m_handler); + } + else + { + m_comparators[i].m_handler_index= idx; // Non-unique handler + } + } +} + + +bool Predicant_to_list_comparator::make_unique_cmp_items(THD *thd, + CHARSET_INFO *cs) +{ + for (uint i= 0; i < m_comparator_count; i++) + { + if (m_comparators[i].m_handler && // Skip implicit NULLs + m_comparators[i].m_handler_index == i && // Skip non-unuque + !(m_comparators[i].m_cmp_item= + m_comparators[i].m_handler->make_cmp_item(thd, cs))) + return true; + } + return false; +} + + cmp_item* cmp_item::get_comparator(Item_result type, Item *warn_item, CHARSET_INFO *cs) { @@ -3804,7 +3885,9 @@ cmp_item* cmp_item::get_comparator(Item_result type, Item *warn_item, return new cmp_item_decimal; case TIME_RESULT: DBUG_ASSERT(warn_item); - return new cmp_item_datetime(warn_item); + return warn_item->field_type() == MYSQL_TYPE_TIME ? + (cmp_item *) new cmp_item_time() : + (cmp_item *) new cmp_item_datetime(); } return 0; // to satisfy compiler :) } @@ -3996,12 +4079,11 @@ cmp_item* cmp_item_decimal::make_same() } -void cmp_item_datetime::store_value(Item *item) +void cmp_item_temporal::store_value_internal(Item *item, + enum_field_types f_type) { bool is_null; Item **tmp_item= lval_cache ? &lval_cache : &item; - enum_field_types f_type= - tmp_item[0]->field_type_for_temporal_comparison(warn_item); value= get_datetime_value(thd, &tmp_item, &lval_cache, f_type, &is_null); m_null_value= item->null_value; } @@ -4009,21 +4091,34 @@ void cmp_item_datetime::store_value(Item *item) int cmp_item_datetime::cmp(Item *arg) { - const bool rc= value != arg->val_temporal_packed(warn_item); + const bool rc= value != arg->val_datetime_packed(); return (m_null_value || arg->null_value) ? UNKNOWN : rc; } -int cmp_item_datetime::compare(cmp_item *ci) +int cmp_item_time::cmp(Item *arg) { - cmp_item_datetime *l_cmp= (cmp_item_datetime *)ci; + const bool rc= value != arg->val_time_packed(); + return (m_null_value || arg->null_value) ? UNKNOWN : rc; +} + + +int cmp_item_temporal::compare(cmp_item *ci) +{ + cmp_item_temporal *l_cmp= (cmp_item_temporal *)ci; return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1); } cmp_item *cmp_item_datetime::make_same() { - return new cmp_item_datetime(warn_item); + return new cmp_item_datetime(); +} + + +cmp_item *cmp_item_time::make_same() +{ + return new cmp_item_time(); } @@ -4115,43 +4210,49 @@ void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref) } +bool Item_func_in::prepare_predicant_and_values(THD *thd, uint *found_types) +{ + uint type_cnt; + have_null= false; + + add_predicant(this, 0); + for (uint i= 1 ; i < arg_count; i++) + { + if (add_value_skip_null(this, i, &have_null)) + return true; + } + all_values_added(&m_comparator, &type_cnt, found_types); + arg_types_compatible= type_cnt < 2; + +#ifndef DBUG_OFF + Predicant_to_list_comparator::debug_print(thd); +#endif + return false; +} + + void Item_func_in::fix_length_and_dec() { THD *thd= current_thd; - uint found_types= 0; - uint type_cnt= 0, i; - m_comparator.set_handler(&type_handler_varchar); - left_cmp_type= args[0]->cmp_type(); + uint found_types; + m_comparator.set_handler(type_handler_varchar.type_handler_for_comparison()); max_length= 1; - if (!(found_types= collect_cmp_types(args, arg_count, true))) - return; - - for (i= 0; i <= (uint)TIME_RESULT; i++) + + if (prepare_predicant_and_values(thd, &found_types)) { - if (found_types & (1U << i)) - { - (type_cnt)++; - if ((Item_result) i == TIME_RESULT) - { - Item *date_arg= find_date_time_item(args, arg_count, 0); - m_comparator.set_handler(date_arg ? date_arg->type_handler() : - &type_handler_datetime); - } - else - m_comparator.set_handler_by_cmp_type((Item_result) i); - } + DBUG_ASSERT(thd->is_error()); // Must set error + return; } - if (type_cnt == 1) // Bisection condition #1 + if (arg_types_compatible) // Bisection condition #1 { - arg_types_compatible= true; m_comparator.type_handler()-> Item_func_in_fix_comparator_compatible_types(thd, this); } else { DBUG_ASSERT(m_comparator.cmp_type() != ROW_RESULT); - fix_for_scalar_comparison_using_cmp_items(found_types); + fix_for_scalar_comparison_using_cmp_items(thd, found_types); } DBUG_EXECUTE_IF("Item_func_in", @@ -4164,6 +4265,11 @@ void Item_func_in::fix_length_and_dec() /** Populate Item_func_in::array with constant not-NULL arguments and sort them. + + Sets "have_null" to true if some of the values appeared to be NULL. + Note, explicit NULLs were found during prepare_predicant_and_values(). + So "have_null" can already be true before the fix_in_vector() call. + Here we additionally catch implicit NULLs. */ void Item_func_in::fix_in_vector() { @@ -4236,7 +4342,12 @@ bool cmp_item_row::prepare_comparators(THD *thd, Item **args, uint arg_count) Item *date_arg= find_date_time_item(args, arg_count, col); if (date_arg) { - if (!(comparators[col]= new (thd->mem_root) cmp_item_datetime(date_arg))) + // TODO: do like the scalar comparators do + const Type_handler *h= date_arg->type_handler(); + comparators[col]= h->field_type() == MYSQL_TYPE_TIME ? + (cmp_item *) new (thd->mem_root) cmp_item_time() : + (cmp_item *) new (thd->mem_root) cmp_item_datetime(); + if (!comparators[col]) return true; } } @@ -4275,24 +4386,14 @@ bool Item_func_in::fix_for_row_comparison_using_bisection(THD *thd) The pair {args[0],args[1]} is compared by type_handler_decimal. The pair {args[0],args[2]} is compared by type_handler_double. */ -bool Item_func_in::fix_for_scalar_comparison_using_cmp_items(uint found_types) +bool Item_func_in::fix_for_scalar_comparison_using_cmp_items(THD *thd, + uint found_types) { - Item *date_arg; - if (found_types & (1U << TIME_RESULT)) - date_arg= find_date_time_item(args, arg_count, 0); if (found_types & (1U << STRING_RESULT) && agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) return true; - for (uint i= 0; i <= (uint) TIME_RESULT; i++) - { - if (found_types & (1U << i) && !cmp_items[i]) - { - if (!cmp_items[i] && !(cmp_items[i]= - cmp_item::get_comparator((Item_result)i, date_arg, - cmp_collation.collation))) - return true; - } - } + if (make_unique_cmp_items(thd, cmp_collation.collation)) + return true; return false; } @@ -4302,14 +4403,13 @@ bool Item_func_in::fix_for_scalar_comparison_using_cmp_items(uint found_types) */ bool Item_func_in::fix_for_row_comparison_using_cmp_items(THD *thd) { - uint cols= args[0]->cols(); - cmp_item_row *cmp_row; - if (!(cmp_row= new (thd->mem_root) cmp_item_row) || - cmp_row->alloc_comparators(thd, cols) || - cmp_row->prepare_comparators(thd, args, arg_count)) + if (make_unique_cmp_items(thd, cmp_collation.collation)) return true; - cmp_items[ROW_RESULT]= cmp_row; - return false; + DBUG_ASSERT(get_comparator_type_handler(0) == &type_handler_row); + DBUG_ASSERT(get_comparator_cmp_item(0)); + cmp_item_row *cmp_row= (cmp_item_row*) get_comparator_cmp_item(0); + return cmp_row->alloc_comparators(thd, args[0]->cols()) || + cmp_row->prepare_comparators(thd, args, arg_count); } @@ -4351,9 +4451,7 @@ void Item_func_in::print(String *str, enum_query_type query_type) longlong Item_func_in::val_int() { - cmp_item *in_item; DBUG_ASSERT(fixed == 1); - uint value_added_map= 0; if (array) { bool tmp=array->find(args[0]); @@ -4371,29 +4469,13 @@ longlong Item_func_in::val_int() if ((null_value= args[0]->real_item()->type() == NULL_ITEM)) return 0; - have_null= 0; - for (uint i= 1 ; i < arg_count ; i++) - { - if (args[i]->real_item()->type() == NULL_ITEM) - { - have_null= TRUE; - continue; - } - Item_result cmp_type= item_cmp_type(left_cmp_type, args[i]); - in_item= cmp_items[(uint)cmp_type]; - DBUG_ASSERT(in_item); - if (!(value_added_map & (1U << (uint)cmp_type))) - { - in_item->store_value(args[0]); - value_added_map|= 1U << (uint)cmp_type; - } - const int rc= in_item->cmp(args[i]); - if (rc == FALSE) - return (longlong) (!negated); - have_null|= (rc == UNKNOWN); - } - null_value= have_null; + uint idx; + if (!Predicant_to_list_comparator::cmp(this, &idx, &null_value)) + { + null_value= false; + return (longlong) (!negated); + } return (longlong) (!null_value && negated); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 9749dabb88b..ccce7b30996 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1462,21 +1462,48 @@ public: If the left item is a constant one then its value is cached in the lval_cache variable. */ -class cmp_item_datetime : public cmp_item_scalar +class cmp_item_temporal: public cmp_item_scalar { +protected: longlong value; + void store_value_internal(Item *item, enum_field_types type); public: THD *thd; - /* Item used for issuing warnings. */ - Item *warn_item; /* Cache for the left item. */ Item *lval_cache; - cmp_item_datetime(Item *warn_item_arg) - :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {} - void store_value(Item *item); - int cmp(Item *arg); + cmp_item_temporal() + :thd(current_thd), lval_cache(0) {} int compare(cmp_item *ci); +}; + + +class cmp_item_datetime: public cmp_item_temporal +{ +public: + cmp_item_datetime() + :cmp_item_temporal() + { } + void store_value(Item *item) + { + store_value_internal(item, MYSQL_TYPE_DATETIME); + } + int cmp(Item *arg); + cmp_item *make_same(); +}; + + +class cmp_item_time: public cmp_item_temporal +{ +public: + cmp_item_time() + :cmp_item_temporal() + { } + void store_value(Item *item) + { + store_value_internal(item, MYSQL_TYPE_TIME); + } + int cmp(Item *arg); cmp_item *make_same(); }; @@ -1551,6 +1578,326 @@ public: }; +/** + A helper class to handle situations when some item "pred" (the predicant) + is consequently compared to a list of other items value0..valueN (the values). + Currently used to handle: + - + pred IN (value0, value1, value2) + - + CASE pred WHEN value0 .. WHEN value1 .. WHEN value2 .. END + + Every pair {pred,valueN} can be compared by its own Type_handler. + Some pairs can use the same Type_handler. + In cases when all pairs use exactly the same Type_handler, + we say "all types are compatible". + + For example, for an expression + 1 IN (1, 1e0, 1.0, 2) + - pred is 1 + - value0 is 1 + - value1 is 1e0 + - value2 is 1.1 + - value3 is 2 + + Pairs (pred,valueN) are compared as follows: + N expr1 Type + - ----- ---- + 0 1 INT + 1 1e0 DOUBLE + 2 1.0 DECIMAL + 3 2 INT + + Types are not compatible in this example. + + During add_value() calls, each pair {pred,valueN} is analysed: + - If valueN is an explicit NULL, it can be ignored in the caller asks to do so + - If valueN is not an explicit NULL (or if the caller didn't ask to skip + NULLs), then the value add an element in the array m_comparators[]. + + Every element m_comparators[] stores the following information: + 1. m_arg_index - the position of the value expression in the original + argument array, e.g. in Item_func_in::args[] or Item_func_case::args[]. + + 2. m_handler - the pointer to the data type handler that the owner + will use to compare the pair {args[m_predicate_index],args[m_arg_index]}. + + 3. m_handler_index - the index of an m_comparators[] element corresponding + to the leftmost pair that uses exactly the same Type_handler for + comparison. m_handler_index helps to maintain unique data type handlers. + - m_comparators[i].m_handler_index==i means that this is the + leftmost pair that uses the Type_handler m_handler for comparision. + - If m_comparators[i].m_handlex_index!=i, it means that some earlier + element m_comparators[jm_cmp_item; + DBUG_ASSERT(in_item); + /* + If this is the leftmost pair that uses the data type handler + pointed by m_comparators[i].m_handler, then we need to cache + the predicant value representation used by this handler. + */ + if (m_comparators[i].m_handler_index == i) + in_item->store_value(args->arguments()[m_predicant_index]); + /* + If the predicant item has null_value==true then: + - In case of scalar expression we can returns UNKNOWN immediately. + No needs to check the result of the value item. + - In case of ROW, null_value==true means that *some* row elements + returned NULL, but *some* elements can still be non-NULL! + We need to get the result of the value item and test + if non-NULL elements in the predicant and the value produce + TRUE (not equal), or UNKNOWN. + */ + if (args->arguments()[m_predicant_index]->null_value && + m_comparators[i].m_handler != &type_handler_row) + return UNKNOWN; + return in_item->cmp(args->arguments()[m_comparators[i].m_arg_index]); + } + + /** + Predicant_to_value_comparator - a comparator for one pair (pred,valueN). + See comments above. + */ + struct Predicant_to_value_comparator + { + const Type_handler *m_handler; + cmp_item *m_cmp_item; + uint m_arg_index; + uint m_handler_index; + void cleanup() + { + if (m_cmp_item) + delete m_cmp_item; + memset(this, 0, sizeof(*this)); + } + }; + + Predicant_to_value_comparator *m_comparators; // The comparator array + uint m_comparator_count;// The number of elements in m_comparators[] + uint m_predicant_index; // The position of the predicant in its argument list, + // e.g. for Item_func_in m_predicant_index is 0, + // as predicant is stored in Item_func_in::args[0]. + // For Item_func_case m_predicant_index is + // set to Item_func_case::first_expr_num. + +public: + Predicant_to_list_comparator(THD *thd, uint nvalues) + :m_comparator_count(0), + m_predicant_index(0) + { + alloc_comparators(thd, nvalues); + } + + uint comparator_count() const { return m_comparator_count; } + const Type_handler *get_comparator_type_handler(uint i) const + { + DBUG_ASSERT(i < m_comparator_count); + return m_comparators[i].m_handler; + } + uint get_comparator_arg_index(uint i) const + { + DBUG_ASSERT(i < m_comparator_count); + return m_comparators[i].m_arg_index; + } + cmp_item *get_comparator_cmp_item(uint i) const + { + DBUG_ASSERT(i < m_comparator_count); + return m_comparators[i].m_cmp_item; + } + +#ifndef DBUG_OFF + void debug_print(THD *thd) + { + for (uint i= 0; i < m_comparator_count; i++) + { + DBUG_EXECUTE_IF("Predicant_to_list_comparator", + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "DBUG: [%d] arg=%d handler=%d", i, + m_comparators[i].m_arg_index, + m_comparators[i].m_handler_index);); + } + } +#endif + + void add_predicant(Item_args *args, uint predicant_index) + { + DBUG_ASSERT(m_comparator_count == 0); // Set in constructor + DBUG_ASSERT(m_predicant_index == 0); // Set in constructor + DBUG_ASSERT(predicant_index < args->argument_count()); + m_predicant_index= predicant_index; + } + /** + Add a new element into m_comparators[], using a {pred,valueN} pair. + + @param args - the owner function's argument list + @param value_index - the value position in args + @retval true - could not add an element because of non-comparable + arguments (e.g. ROWs with size) + @retval false - a new element was successfully added. + */ + bool add_value(Item_args *args, uint value_index); + + /** + Add a new element into m_comparators[], ignoring explicit NULL values. + If the value appeared to be an explicit NULL, nulls_found[0] is set to true. + */ + bool add_value_skip_null(Item_args *args, uint value_index, + bool *nulls_found); + + /** + Signal "this" that there will be no new add_value*() calls, + so it can prepare its internal structures for comparison. + + @param [OUT] compatible - If all comparators are compatible, + their data type handler is returned here. + @param [OUT] unuque_cnt - The number of unique data type handlers found. + If the value returned in *unique_cnt is 0, + it means all values were explicit NULLs: + expr0 IN (NULL,NULL,..,NULL) + @param [OUT] found_type - The bit mask for all found cmp_type()'s. + */ + void all_values_added(Type_handler_hybrid_field_type *compatible, + uint *unique_cnt, uint *found_types) + { + detect_unique_handlers(compatible, unique_cnt, found_types); + } + /** + Creates cmp_item instances for all unique handlers and stores + them into m_comparators[].m_cmp_item, using the information previously + populated by add_predicant(), add_value() and detect_unque_handlers(). + */ + bool make_unique_cmp_items(THD *thd, CHARSET_INFO *cs); + void cleanup() + { + DBUG_ASSERT(m_comparators); + for (uint i= 0; i < m_comparator_count; i++) + m_comparators[i].cleanup(); + memset(m_comparators, 0, sizeof(m_comparators[0]) * m_comparator_count); + m_comparator_count= 0; + m_predicant_index= 0; + } + bool init_clone(THD *thd, uint nvalues) + { + m_comparator_count= 0; + m_predicant_index= 0; + return alloc_comparators(thd, nvalues); + } + /** + @param [IN] args - The argument list that was previously used with + add_predicant() and add_value(). + @param [OUT] idx - In case if a value that is equal to the predicant + was found, the index of the matching value is returned + here. Otherwise, *idx is not changed. + @param [IN/OUT] found_unknown_values - how to handle UNKNOWN results. + If found_unknown_values is NULL (e.g. Item_func_case), + cmp() returns immediately when the first UNKNOWN + result is found. + If found_unknown_values is non-NULL (Item_func_in), + cmp() does not return when an UNKNOWN result is found, + sets *found_unknown_values to true, and continues + to compare the remaining pairs to find FALSE + (i.e. the value that is equal to the predicant). + + @retval false - Found a value that is equal to the predicant + @retval true - Didn't find an equal value + */ + bool cmp(Item_args *args, uint *idx, bool *found_unknown_values) + { + for (uint i= 0 ; i < m_comparator_count ; i++) + { + DBUG_ASSERT(m_comparators[i].m_handler != NULL); + const int rc= cmp_arg(args, i); + if (rc == FALSE) + { + *idx= m_comparators[i].m_arg_index; + return false; // Found a matching value + } + if (rc == UNKNOWN) + { + if (!found_unknown_values) + return true; + *found_unknown_values= true; + } + } + return true; // Not found + } + +}; + + /* The class Item_func_case is the CASE ... WHEN ... THEN ... END function implementation. @@ -1569,18 +1916,17 @@ public: function and only comparators for there result types are used. */ -class Item_func_case :public Item_func_hybrid_field_type +class Item_func_case :public Item_func_hybrid_field_type, + public Predicant_to_list_comparator { int first_expr_num, else_expr_num; enum Item_result left_cmp_type; String tmp_value; uint ncases; - Item_result cmp_type; DTCollation cmp_collation; - cmp_item *cmp_items[6]; /* For all result types */ - cmp_item *case_item; Item **arg_buffer; uint m_found_types; + bool prepare_predicant_and_values(THD *thd, uint *found_types); public: Item_func_case(THD *thd, List &list, Item *first_expr_arg, Item *else_expr_arg); @@ -1598,7 +1944,13 @@ public: virtual void print(String *str, enum_query_type query_type); Item *find_item(String *str); CHARSET_INFO *compare_collation() const { return cmp_collation.collation; } - void cleanup(); + void cleanup() + { + DBUG_ENTER("Item_func_case::cleanup"); + Item_func::cleanup(); + Predicant_to_list_comparator::cleanup(); + DBUG_VOID_RETURN; + } Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond); bool need_parentheses_in_default() { return true; } Item *get_copy(THD *thd, MEM_ROOT *mem_root) @@ -1608,9 +1960,9 @@ public: Item_func_case *clone= (Item_func_case *) Item_func::build_clone(thd, mem_root); if (clone) { - clone->case_item= 0; clone->arg_buffer= 0; - bzero(&clone->cmp_items, sizeof(cmp_items)); + if (clone->Predicant_to_list_comparator::init_clone(thd, ncases)) + return NULL; } return clone; } @@ -1643,7 +1995,8 @@ public: 3. UNKNOWN and FALSE are equivalent results 4. Neither left expression nor contain any NULL value */ -class Item_func_in :public Item_func_opt_neg +class Item_func_in :public Item_func_opt_neg, + public Predicant_to_list_comparator { /** Usable if is made only of constants. Returns true if one @@ -1660,6 +2013,7 @@ class Item_func_in :public Item_func_opt_neg } return true; } + bool prepare_predicant_and_values(THD *thd, uint *found_types); protected: SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Field *field, Item *value); @@ -1678,14 +2032,13 @@ public: and can be used safely as comparisons for key conditions */ bool arg_types_compatible; - Item_result left_cmp_type; - cmp_item *cmp_items[6]; /* One cmp_item for each result type */ Item_func_in(THD *thd, List &list): - Item_func_opt_neg(thd, list), array(0), have_null(0), + Item_func_opt_neg(thd, list), + Predicant_to_list_comparator(thd, arg_count - 1), + array(0), have_null(0), arg_types_compatible(FALSE) { - bzero(&cmp_items, sizeof(cmp_items)); allowed_arg_cols= 0; // Fetch this value from first argument } longlong val_int(); @@ -1702,7 +2055,6 @@ public: return all_items_are_consts(args + 1, arg_count - 1) && // Bisection #2 ((is_top_level_item() && !negated) || // Bisection #3 (!list_contains_null() && !args[0]->maybe_null)); // Bisection #4 - } bool agg_all_arg_charsets_for_comparison() { @@ -1718,23 +2070,18 @@ public: fix_in_vector(); return false; } - bool fix_for_scalar_comparison_using_cmp_items(uint found_types); + bool fix_for_scalar_comparison_using_cmp_items(THD *thd, uint found_types); bool fix_for_row_comparison_using_cmp_items(THD *thd); bool fix_for_row_comparison_using_bisection(THD *thd); void cleanup() { - uint i; DBUG_ENTER("Item_func_in::cleanup"); Item_int_func::cleanup(); delete array; array= 0; - for (i= 0; i <= (uint)TIME_RESULT; i++) - { - delete cmp_items[i]; - cmp_items[i]= 0; - } + Predicant_to_list_comparator::cleanup(); DBUG_VOID_RETURN; } void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, @@ -1747,13 +2094,20 @@ public: will be replaced to a zero-filled Item_string. Such a change would require rebuilding of cmp_items. */ - Context cmpctx(ANY_SUBST, m_comparator.cmp_type(), - Item_func_in::compare_collation()); - for (uint i= 0; i < arg_count; i++) + if (arg_types_compatible) { - if (arg_types_compatible || i > 0) - args[i]->propagate_equal_fields_and_change_item_tree(thd, cmpctx, - cond, &args[i]); + Context cmpctx(ANY_SUBST, m_comparator.cmp_type(), + Item_func_in::compare_collation()); + args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx, + cond, &args[0]); + } + for (uint i= 0; i < comparator_count(); i++) + { + Context cmpctx(ANY_SUBST, get_comparator_type_handler(i)->cmp_type(), + Item_func_in::compare_collation()); + uint idx= get_comparator_arg_index(i); + args[idx]->propagate_equal_fields_and_change_item_tree(thd, cmpctx, + cond, &args[idx]); } return this; } @@ -1772,7 +2126,8 @@ public: if (clone) { clone->array= 0; - bzero(&clone->cmp_items, sizeof(cmp_items)); + if (clone->Predicant_to_list_comparator::init_clone(thd, arg_count - 1)) + return NULL; } return clone; } diff --git a/sql/sql_type.cc b/sql/sql_type.cc index cc87c8e14e4..b7dd4c23ade 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -123,6 +123,49 @@ Type_handler_hybrid_field_type::Type_handler_hybrid_field_type() } +/***************************************************************************/ + +const Type_handler *Type_handler_int_result::type_handler_for_comparison() const +{ + return &type_handler_longlong; +} + + +const Type_handler *Type_handler_string_result::type_handler_for_comparison() const +{ + return &type_handler_long_blob; +} + + +const Type_handler *Type_handler_decimal_result::type_handler_for_comparison() const +{ + return &type_handler_newdecimal; +} + + +const Type_handler *Type_handler_real_result::type_handler_for_comparison() const +{ + return &type_handler_double; +} + + +const Type_handler *Type_handler_time_common::type_handler_for_comparison() const +{ + return &type_handler_time; +} + +const Type_handler *Type_handler_temporal_with_date::type_handler_for_comparison() const +{ + return &type_handler_datetime; +} + + +const Type_handler *Type_handler_row::type_handler_for_comparison() const +{ + return &type_handler_row; +} + + /** Collect built-in data type handlers for comparison. This method is very similar to item_cmp_type() defined in item.cc. @@ -135,6 +178,8 @@ Type_handler_hybrid_field_type::Type_handler_hybrid_field_type() void Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h) { + DBUG_ASSERT(m_type_handler == m_type_handler->type_handler_for_comparison()); + DBUG_ASSERT(h == h->type_handler_for_comparison()); Item_result a= cmp_type(); Item_result b= h->cmp_type(); if (a == STRING_RESULT && b == STRING_RESULT) @@ -170,9 +215,12 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h) } else m_type_handler= &type_handler_double; + DBUG_ASSERT(m_type_handler == m_type_handler->type_handler_for_comparison()); } +/***************************************************************************/ + const Type_handler * Type_handler::get_handler_by_field_type(enum_field_types type) { @@ -1263,6 +1311,51 @@ longlong Type_handler_decimal_result:: /***************************************************************************/ +cmp_item *Type_handler_int_result::make_cmp_item(THD *thd, + CHARSET_INFO *cs) const +{ + return new (thd->mem_root) cmp_item_int; +} + +cmp_item *Type_handler_real_result::make_cmp_item(THD *thd, + CHARSET_INFO *cs) const +{ + return new (thd->mem_root) cmp_item_real; +} + +cmp_item *Type_handler_decimal_result::make_cmp_item(THD *thd, + CHARSET_INFO *cs) const +{ + return new (thd->mem_root) cmp_item_decimal; +} + + +cmp_item *Type_handler_string_result::make_cmp_item(THD *thd, + CHARSET_INFO *cs) const +{ + return new (thd->mem_root) cmp_item_sort_string(cs); +} + +cmp_item *Type_handler_row::make_cmp_item(THD *thd, + CHARSET_INFO *cs) const +{ + return new (thd->mem_root) cmp_item_row; +} + +cmp_item *Type_handler_time_common::make_cmp_item(THD *thd, + CHARSET_INFO *cs) const +{ + return new (thd->mem_root) cmp_item_time; +} + +cmp_item *Type_handler_temporal_with_date::make_cmp_item(THD *thd, + CHARSET_INFO *cs) const +{ + return new (thd->mem_root) cmp_item_datetime; +} + +/***************************************************************************/ + static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) { return cs->coll->strnncollsp(cs, @@ -1342,7 +1435,8 @@ bool Type_handler_string_result:: func->fix_for_scalar_comparison_using_bisection(thd); } return - func->fix_for_scalar_comparison_using_cmp_items(1U << (uint) STRING_RESULT); + func->fix_for_scalar_comparison_using_cmp_items(thd, + 1U << (uint) STRING_RESULT); } @@ -1356,7 +1450,8 @@ bool Type_handler_int_result:: */ return func->compatible_types_scalar_bisection_possible() ? func->fix_for_scalar_comparison_using_bisection(thd) : - func->fix_for_scalar_comparison_using_cmp_items(1U << (uint) INT_RESULT); + func->fix_for_scalar_comparison_using_cmp_items(thd, + 1U << (uint) INT_RESULT); } @@ -1367,7 +1462,8 @@ bool Type_handler_real_result:: return func->compatible_types_scalar_bisection_possible() ? (func->value_list_convert_const_to_int(thd) || func->fix_for_scalar_comparison_using_bisection(thd)) : - func->fix_for_scalar_comparison_using_cmp_items(1U << (uint) REAL_RESULT); + func->fix_for_scalar_comparison_using_cmp_items(thd, + 1U << (uint) REAL_RESULT); } @@ -1378,7 +1474,8 @@ bool Type_handler_decimal_result:: return func->compatible_types_scalar_bisection_possible() ? (func->value_list_convert_const_to_int(thd) || func->fix_for_scalar_comparison_using_bisection(thd)) : - func->fix_for_scalar_comparison_using_cmp_items(1U << (uint) DECIMAL_RESULT); + func->fix_for_scalar_comparison_using_cmp_items(thd, + 1U << (uint) DECIMAL_RESULT); } @@ -1389,7 +1486,8 @@ bool Type_handler_temporal_result:: return func->compatible_types_scalar_bisection_possible() ? (func->value_list_convert_const_to_int(thd) || func->fix_for_scalar_comparison_using_bisection(thd)) : - func->fix_for_scalar_comparison_using_cmp_items(1U << (uint) TIME_RESULT); + func->fix_for_scalar_comparison_using_cmp_items(thd, + 1U << (uint) TIME_RESULT); } diff --git a/sql/sql_type.h b/sql/sql_type.h index d9bc0eb94a2..1f82f5bbeb0 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -31,6 +31,7 @@ class Item_func_hex; class Item_func_hybrid_field_type; class Item_func_between; class Item_func_in; +class cmp_item; class in_vector; class Type_std_attributes; class Sort_param; @@ -243,6 +244,7 @@ public: virtual enum_field_types real_field_type() const { return field_type(); } virtual Item_result result_type() const= 0; virtual Item_result cmp_type() const= 0; + virtual const Type_handler *type_handler_for_comparison() const= 0; virtual const Type_handler* type_handler_adjusted_to_max_octet_length(uint max_octet_length, CHARSET_INFO *cs) const @@ -321,6 +323,9 @@ public: virtual longlong Item_func_between_val_int(Item_func_between *func) const= 0; + virtual cmp_item * + make_cmp_item(THD *thd, CHARSET_INFO *cs) const= 0; + virtual in_vector * make_in_vector(THD *thd, const Item_func_in *func, uint nargs) const= 0; @@ -350,6 +355,7 @@ public: { return ROW_RESULT; } + const Type_handler *type_handler_for_comparison() const; Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const { DBUG_ASSERT(0); @@ -429,6 +435,7 @@ public: } longlong Item_func_between_val_int(Item_func_between *func) const; + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *thd, const Item_func_in *f, uint nargs) const; bool Item_func_in_fix_comparator_compatible_types(THD *thd, Item_func_in *) const; @@ -457,6 +464,7 @@ public: Item_result result_type() const { return REAL_RESULT; } Item_result cmp_type() const { return REAL_RESULT; } virtual ~Type_handler_real_result() {} + const Type_handler *type_handler_for_comparison() const; void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, Sort_param *param) const; void sortlength(THD *thd, @@ -480,6 +488,7 @@ public: MYSQL_TIME *, ulonglong fuzzydate) const; longlong Item_func_between_val_int(Item_func_between *func) const; + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; bool Item_func_in_fix_comparator_compatible_types(THD *thd, Item_func_in *) const; @@ -493,6 +502,7 @@ public: Item_result result_type() const { return DECIMAL_RESULT; } Item_result cmp_type() const { return DECIMAL_RESULT; } virtual ~Type_handler_decimal_result() {}; + const Type_handler *type_handler_for_comparison() const; Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const; void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, Sort_param *param) const; @@ -518,6 +528,7 @@ public: MYSQL_TIME *, ulonglong fuzzydate) const; longlong Item_func_between_val_int(Item_func_between *func) const; + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; bool Item_func_in_fix_comparator_compatible_types(THD *thd, Item_func_in *) const; @@ -530,6 +541,7 @@ public: Item_result result_type() const { return INT_RESULT; } Item_result cmp_type() const { return INT_RESULT; } virtual ~Type_handler_int_result() {} + const Type_handler *type_handler_for_comparison() const; Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const; void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, Sort_param *param) const; @@ -554,6 +566,7 @@ public: MYSQL_TIME *, ulonglong fuzzydate) const; longlong Item_func_between_val_int(Item_func_between *func) const; + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; bool Item_func_in_fix_comparator_compatible_types(THD *thd, Item_func_in *) const; @@ -600,6 +613,7 @@ public: Item_result result_type() const { return STRING_RESULT; } Item_result cmp_type() const { return STRING_RESULT; } virtual ~Type_handler_string_result() {} + const Type_handler *type_handler_for_comparison() const; const Type_handler * type_handler_adjusted_to_max_octet_length(uint max_octet_length, CHARSET_INFO *cs) const; @@ -627,6 +641,7 @@ public: MYSQL_TIME *, ulonglong fuzzydate) const; longlong Item_func_between_val_int(Item_func_between *func) const; + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; bool Item_func_in_fix_comparator_compatible_types(THD *thd, Item_func_in *) const; @@ -761,7 +776,9 @@ class Type_handler_time_common: public Type_handler_temporal_result public: virtual ~Type_handler_time_common() { } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } + const Type_handler *type_handler_for_comparison() const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; }; @@ -789,7 +806,9 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result { public: virtual ~Type_handler_temporal_with_date() {} + const Type_handler *type_handler_for_comparison() const; int Item_save_in_field(Item *item, Field *field, bool no_conversions) const; + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const; in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const; };