diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index e08872a648b..b7d2b5bb270 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1371,3 +1371,41 @@ SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0); pk 2 DROP TABLE t1, t2; +# +# LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value' +# failed with subquery on both sides of NOT IN and materialization +# +CREATE TABLE t1 (f1a int, f1b int) ; +INSERT IGNORE INTO t1 VALUES (1,1),(2,2); +CREATE TABLE t2 ( f2 int); +INSERT IGNORE INTO t2 VALUES (3),(4); +CREATE TABLE t3 (f3a int, f3b int); +set session optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off'; +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found +SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); +f2 +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found +SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); +f2 +insert into t3 values (1,1),(2,2); +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t2 WHERE (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1); +f2 +3 +4 +drop table t1, t2, t3; diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test index e564ed36040..2664d2a31b4 100644 --- a/mysql-test/t/subselect_mat.test +++ b/mysql-test/t/subselect_mat.test @@ -1011,3 +1011,31 @@ SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0); DROP TABLE t1, t2; +--echo # +--echo # LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value' +--echo # failed with subquery on both sides of NOT IN and materialization +--echo # + +CREATE TABLE t1 (f1a int, f1b int) ; +INSERT IGNORE INTO t1 VALUES (1,1),(2,2); +CREATE TABLE t2 ( f2 int); +INSERT IGNORE INTO t2 VALUES (3),(4); +CREATE TABLE t3 (f3a int, f3b int); + +set session optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off'; + +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); +SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); + +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); +SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); + +insert into t3 values (1,1),(2,2); + +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1); +SELECT * FROM t2 WHERE (SELECT f3a FROM t3 where f3a > 3) NOT IN (SELECT f1a FROM t1); + +drop table t1, t2, t3; diff --git a/sql/item.h b/sql/item.h index 7c4b3c6e819..2340af9fdc6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3342,6 +3342,13 @@ private: }; +/** + @todo + Implement the is_null() method for this class. Currently calling is_null() + on any Item_cache object resolves to Item::is_null(), which reutns FALSE + for any value. +*/ + class Item_cache: public Item_basic_constant { protected: diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index e89f8032e4f..8d10b80d171 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -5069,7 +5069,7 @@ bool subselect_rowid_merge_engine::partial_match() for (uint i= test(non_null_key); i < keys_count; i++) { DBUG_ASSERT(merge_keys[i]->get_column_count() == 1); - if (merge_keys[i]->get_search_key(0)->is_null()) + if (merge_keys[i]->get_search_key(0)->null_value) { ++count_nulls_in_search_key; bitmap_set_bit(&matching_outer_cols, merge_keys[i]->get_keyid());