From 4e91aebdb7e0abc94d655914e933c9f5d2d76655 Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Wed, 13 May 2026 15:41:24 -0400 Subject: [PATCH] MDEV-35291 derived_with_keys not applied for UNION with const filter The optimizer fails to generate a derived key when a materialized UNION derived table is filtered by a constant equality, as in: SELECT dt.* FROM ((SELECT * FROM t1 LIMIT 100) UNION (SELECT * FROM t1 LIMIT 200)) dt WHERE id = 1; The condition cannot be pushed into the underlying SELECTs because LIMIT inside each branch blocks pushdown, so the only remaining optimization is to build a derived key on id and access via ref(const). But add_key_part() registers KEYUSE entries for the materialized derived only when the value side of the equality references another table. That excludes constants, leaving the outer query no choice but to scan the full materialized result. Investigation showed that this is the same defect that Rex Johnston already fixed under MDEV-39499 (see the bb-11.4-MDEV-39499 branch). This commit ports the add_key_part() change from MDEV-39499 to 10.11. --- mysql-test/main/cte_recursive.result | 10 +- mysql-test/main/derived_cond_pushdown.result | 221 ++++++++++++------ .../main/derived_cond_pushdown_innodb.result | 4 +- mysql-test/main/derived_view.result | 71 ++++++ mysql-test/main/derived_view.test | 55 +++++ mysql-test/main/join_nested_jcl6.result | 24 +- mysql-test/main/mrr_derived_crash_4610.result | 2 +- mysql-test/main/subselect3_jcl6.result | 2 +- mysql-test/main/subselect4.result | 14 +- mysql-test/main/subselect_mat.result | 2 +- mysql-test/main/subselect_sj_mat.result | 2 +- .../federatedx_create_handlers.result | 2 +- mysql-test/suite/heap/heap.result | 2 +- sql/sql_select.cc | 74 ++++-- 14 files changed, 362 insertions(+), 123 deletions(-) diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result index a84a99ca3605e..7ad4c17f340ba 100644 --- a/mysql-test/main/cte_recursive.result +++ b/mysql-test/main/cte_recursive.result @@ -1684,16 +1684,16 @@ i div 4 - (i % 4) = ps.i div 4 - (ps.i % 4) ) SELECT regexp_replace(board,concat('(',REPEAT('.', 4),')'),'\\1\n') n_queens FROM solutions WHERE n_queens = 4; n_queens ---*- -*--- ----* --*-- - -*-- ---* *--- --*- +--*- +*--- +---* +-*-- + # # MDEV-10883: execution of prepared statement from SELECT # with recursive CTE that renames columns diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index ff72ea59b8ea0..531d4287b520e 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -8034,7 +8034,7 @@ SELECT * FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2 WHERE f = 8; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY ref key0 key0 5 const 0 0.00 3 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Warnings: Note 1003 /* select#1 */ select `sq1`.`f` AS `f` from (/* select#3 */ select min(`test`.`t1`.`i`) AS `f` from `test`.`t1` having `f` = 8) `sq1` where `sq1`.`f` = 8 @@ -8184,18 +8184,20 @@ EXPLAIN { "query_block": { "select_id": 3, + "outer_ref_condition": "2 is not null", "nested_loop": [ { "table": { "table_name": "", - "access_type": "index_subquery", + "access_type": "ref", "possible_keys": ["key0"], "key": "key0", "key_length": "5", "used_key_parts": ["c"], - "ref": ["func"], - "rows": 2, - "filtered": 100, + "ref": ["const"], + "rows": 0, + "filtered": 0, + "attached_condition": "(t2.b) = v3.c", "materialized": { "query_block": { "select_id": 5, @@ -8361,14 +8363,19 @@ EXPLAIN { "query_block": { "select_id": 3, + "outer_ref_condition": "1 is not null", "nested_loop": [ { "table": { "table_name": "", - "access_type": "ALL", - "rows": 2, - "filtered": 100, - "attached_condition": "v2.b = 1", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["b"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "materialized": { "query_block": { "select_id": 4, @@ -8678,14 +8685,19 @@ EXPLAIN { "query_block": { "select_id": 2, + "outer_ref_condition": "50 is not null", "nested_loop": [ { "table": { "table_name": "", - "access_type": "ALL", - "rows": 2, - "filtered": 100, - "attached_condition": "v1.a = 50", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "materialized": { "query_block": { "select_id": 3, @@ -8820,10 +8832,15 @@ EXPLAIN "sort_key": "v1.a", "table": { "table_name": "", - "access_type": "ALL", - "rows": 2, - "filtered": 100, - "attached_condition": "v1.b = 2", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "4", + "used_key_parts": ["b"], + "ref": ["const"], + "rows": 0, + "filtered": 0, + "attached_condition": "v1.b <=> 2 and v1.b = 2", "materialized": { "query_block": { "select_id": 3, @@ -8889,9 +8906,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 2, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["f"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "v1.f = 2", "materialized": { "query_block": { @@ -8991,9 +9013,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 3, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["i"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "sq.i = 3", "materialized": { "query_block": { @@ -9060,9 +9087,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 3, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["i"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "sq.i = 2.71", "materialized": { "query_block": { @@ -9124,9 +9156,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 3, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "6", + "used_key_parts": ["i"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "sq.i = 3.21", "materialized": { "query_block": { @@ -9188,9 +9225,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 3, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "35", + "used_key_parts": ["i"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "sq.i = 'aa'", "materialized": { "query_block": { @@ -9254,9 +9296,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 3, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "6", + "used_key_parts": ["i"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "sq.i = '2007-05-28 00:00:00'", "materialized": { "query_block": { @@ -9318,9 +9365,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 3, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "4", + "used_key_parts": ["i"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "sq.i = '2007-05-28'", "materialized": { "query_block": { @@ -9382,9 +9434,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 3, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "4", + "used_key_parts": ["i"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "sq.i = '10:00:02'", "materialized": { "query_block": { @@ -9524,9 +9581,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 2, - "filtered": 100, + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "6", + "used_key_parts": ["c"], + "ref": ["const"], + "rows": 0, + "filtered": 0, "attached_condition": "v1.c = 'foo'", "materialized": { "query_block": { @@ -10051,30 +10113,15 @@ EXPLAIN "nested_loop": [ { "table": { - "table_name": "t1", + "table_name": "", "access_type": "ref", - "possible_keys": ["i1"], - "key": "i1", + "possible_keys": ["key0"], + "key": "key0", "key_length": "5", - "used_key_parts": ["i1"], + "used_key_parts": ["i2"], "ref": ["const"], - "rows": 1, - "filtered": 100, - "using_index": true - } - }, - { - "block-nl-join": { - "table": { - "table_name": "", - "access_type": "ALL", - "rows": 2, - "filtered": 100, - "attached_condition": "v2.i2 = 1" - }, - "buffer_type": "flat", - "buffer_size": "65", - "join_type": "BNL", + "rows": 0, + "filtered": 0, "materialized": { "query_block": { "select_id": 3, @@ -10092,6 +10139,20 @@ EXPLAIN } } } + }, + { + "table": { + "table_name": "t1", + "access_type": "ref", + "possible_keys": ["i1"], + "key": "i1", + "key_length": "5", + "used_key_parts": ["i1"], + "ref": ["const"], + "rows": 1, + "filtered": 100, + "using_index": true + } } ] } @@ -12241,7 +12302,7 @@ union all select col2, col1 from v2; explain select * from v3 where col1=123; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where +1 PRIMARY ref key0 key0 5 const 0 2 DERIVED t1 ref a a 5 const 1 3 UNION t1 ref a a 5 const 1 # This must use ref accesses for reading table t1, not full scans: @@ -12255,10 +12316,14 @@ EXPLAIN { "table": { "table_name": "", - "access_type": "ALL", - "rows": 2, - "filtered": 100, - "attached_condition": "v3.col1 = 123 and v3.col2 = 321", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "10", + "used_key_parts": ["col2", "col1"], + "ref": ["const", "const"], + "rows": 0, + "filtered": 0, "materialized": { "query_block": { "union_result": { @@ -19651,15 +19716,19 @@ ANALYZE { "table": { "table_name": "", - "access_type": "ALL", + "access_type": "ref", + "possible_keys": ["key0"], + "key": "key0", + "key_length": "5", + "used_key_parts": ["a"], + "ref": ["const"], "r_loops": 1, - "rows": 4, - "r_rows": 2, + "rows": 0, + "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 100, - "r_filtered": 50, - "attached_condition": "v1.a = 3", + "filtered": 0, + "r_filtered": 100, "materialized": { "query_block": { "union_result": { diff --git a/mysql-test/main/derived_cond_pushdown_innodb.result b/mysql-test/main/derived_cond_pushdown_innodb.result index d01ce8cdd20a3..d7184cdf2aa2e 100644 --- a/mysql-test/main/derived_cond_pushdown_innodb.result +++ b/mysql-test/main/derived_cond_pushdown_innodb.result @@ -15,7 +15,7 @@ JOIN ON CHARSET(dt2_c2) BETWEEN dt1_c1 AND dt1_c1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY system NULL NULL NULL NULL 1 100.00 -1 PRIMARY ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY ref key0 key0 9 const 0 0.00 Using where 3 DERIVED t2 system NULL NULL NULL NULL 1 100.00 2 DERIVED t1 ref c1 c1 9 const 1 100.00 Using where; Using index Warnings: @@ -29,7 +29,7 @@ JOIN ON COERCIBILITY(dt2_c2) BETWEEN dt1_c1 AND dt1_c1; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY system NULL NULL NULL NULL 1 100.00 -1 PRIMARY ALL NULL NULL NULL NULL 2 100.00 Using where +1 PRIMARY ref key0 key0 9 const 0 0.00 Using where 3 DERIVED t2 system NULL NULL NULL NULL 1 100.00 2 DERIVED t1 ref c1 c1 9 const 1 100.00 Using where; Using index Warnings: diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index 3f3f68154882c..19e02b1c9421b 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -4430,3 +4430,74 @@ deallocate prepare stmt; drop view v1,v2; drop table t1,t2; # End of 10.6 tests +# +# MDEV-35291: derived_with_keys not applied for a UNION derived +# filtered by a constant equality in the outer WHERE +# +CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, notes TEXT NOT NULL); +INSERT INTO t1 VALUES (1, 'test1'), (2, 'test2'); +INSERT INTO t1 SELECT seq, seq FROM seq_10_to_1000; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze Warning Engine-independent statistics are not collected for column 'notes' +test.t1 analyze status OK +# Reference plan: UNION derived joined with another table on a +# column equality. derived_with_keys creates key0 (existing +# behaviour). +EXPLAIN +SELECT dt.* FROM +((SELECT id, notes FROM t1 LIMIT 100) UNION +(SELECT id, notes FROM t1 LIMIT 200)) dt, seq_1_to_10 SEQ +WHERE dt.id = SEQ.seq; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY SEQ index PRIMARY PRIMARY 8 NULL 10 Using index +1 PRIMARY ref key0 key0 4 test.SEQ.seq 10 Using index condition +2 DERIVED t1 ALL NULL NULL NULL NULL 993 +3 UNION t1 ALL NULL NULL NULL NULL 993 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +# Bug case: same UNION derived, filtered by a constant equality. +# LIMIT inside each branch blocks condition pushdown, so +# derived_with_keys must step in and provide ref(const) on key0. +EXPLAIN +SELECT dt.* FROM +((SELECT * FROM t1 LIMIT 100) UNION +(SELECT * FROM t1 LIMIT 200)) dt +WHERE id = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ref key0 key0 4 const 10 +2 DERIVED t1 ALL NULL NULL NULL NULL 993 +3 UNION t1 ALL NULL NULL NULL NULL 993 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +SELECT dt.* FROM +((SELECT * FROM t1 LIMIT 100) UNION +(SELECT * FROM t1 LIMIT 200)) dt +WHERE id = 1; +id notes +1 test1 +# Grouped derived: the existing condition-pushdown path handles +# the constant filter, so no derived key is generated and access +# stays as a plain scan of the resulting tiny temp table. +EXPLAIN +SELECT v1.* FROM (SELECT id, MAX(notes) m FROM t1 GROUP BY id) v1 +WHERE v1.id = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +2 DERIVED t1 const PRIMARY PRIMARY 4 const 1 +# With derived_with_keys disabled, the bug case falls back to a +# plain scan. +SET @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='derived_with_keys=off'; +EXPLAIN +SELECT dt.* FROM +((SELECT * FROM t1 LIMIT 100) UNION +(SELECT * FROM t1 LIMIT 200)) dt +WHERE id = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 300 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 993 +3 UNION t1 ALL NULL NULL NULL NULL 993 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +SET optimizer_switch= @save_optimizer_switch; +DROP TABLE t1; +# End of 10.11 tests diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test index 4c02d0fa906b4..9f84fb20c83e9 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -2940,3 +2940,58 @@ drop view v1,v2; drop table t1,t2; --echo # End of 10.6 tests + +--echo # +--echo # MDEV-35291: derived_with_keys not applied for a UNION derived +--echo # filtered by a constant equality in the outer WHERE +--echo # + +CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, notes TEXT NOT NULL); +INSERT INTO t1 VALUES (1, 'test1'), (2, 'test2'); +INSERT INTO t1 SELECT seq, seq FROM seq_10_to_1000; +ANALYZE TABLE t1; + +--echo # Reference plan: UNION derived joined with another table on a +--echo # column equality. derived_with_keys creates key0 (existing +--echo # behaviour). +EXPLAIN +SELECT dt.* FROM + ((SELECT id, notes FROM t1 LIMIT 100) UNION + (SELECT id, notes FROM t1 LIMIT 200)) dt, seq_1_to_10 SEQ +WHERE dt.id = SEQ.seq; + +--echo # Bug case: same UNION derived, filtered by a constant equality. +--echo # LIMIT inside each branch blocks condition pushdown, so +--echo # derived_with_keys must step in and provide ref(const) on key0. +EXPLAIN +SELECT dt.* FROM + ((SELECT * FROM t1 LIMIT 100) UNION + (SELECT * FROM t1 LIMIT 200)) dt +WHERE id = 1; + +SELECT dt.* FROM + ((SELECT * FROM t1 LIMIT 100) UNION + (SELECT * FROM t1 LIMIT 200)) dt +WHERE id = 1; + +--echo # Grouped derived: the existing condition-pushdown path handles +--echo # the constant filter, so no derived key is generated and access +--echo # stays as a plain scan of the resulting tiny temp table. +EXPLAIN +SELECT v1.* FROM (SELECT id, MAX(notes) m FROM t1 GROUP BY id) v1 +WHERE v1.id = 1; + +--echo # With derived_with_keys disabled, the bug case falls back to a +--echo # plain scan. +SET @save_optimizer_switch= @@optimizer_switch; +SET optimizer_switch='derived_with_keys=off'; +EXPLAIN +SELECT dt.* FROM + ((SELECT * FROM t1 LIMIT 100) UNION + (SELECT * FROM t1 LIMIT 200)) dt +WHERE id = 1; +SET optimizer_switch= @save_optimizer_switch; + +DROP TABLE t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result index 0a6993e90a5e9..d1bf7d88f8176 100644 --- a/mysql-test/main/join_nested_jcl6.result +++ b/mysql-test/main/join_nested_jcl6.result @@ -558,7 +558,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join) 1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) @@ -653,13 +653,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t9 hash_ALL NULL #hash#$hj 5 const 3 100.00 Using where; Using join buffer (incremental, BNLH join) Warnings: Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null) SELECT t9.a,t9.b @@ -849,7 +849,7 @@ WHERE t1.a <= 2; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) where `test`.`t1`.`a` <= 2 @@ -925,9 +925,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t9 hash_ALL NULL #hash#$hj 5 const 3 100.00 Using where; Using join buffer (incremental, BNLH join) Warnings: Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null) INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0); @@ -972,13 +972,13 @@ t0.b=t1.b AND id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join) -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t9 hash_ALL NULL #hash#$hj 5 const 3 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) @@ -1022,13 +1022,13 @@ t0.b=t1.b AND id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join) -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t9 hash_ALL NULL #hash#$hj 5 const 3 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t8`.`a` >= 0 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) @@ -1072,14 +1072,14 @@ t0.b=t1.b AND (t9.a=1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 -1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t9 hash_ALL NULL #hash#$hj 5 const 3 100.00 Using where; Using join buffer (flat, BNLH join) 1 SIMPLE t1 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan 1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join) -1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 const 2 100.00 Using where; Using join buffer (incremental, BNLH join) 1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan Warnings: Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`b` is not null)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2 and `test`.`t1`.`a` > 0) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) diff --git a/mysql-test/main/mrr_derived_crash_4610.result b/mysql-test/main/mrr_derived_crash_4610.result index 3e38a0d42183b..10b5d7171ce5d 100644 --- a/mysql-test/main/mrr_derived_crash_4610.result +++ b/mysql-test/main/mrr_derived_crash_4610.result @@ -8,7 +8,7 @@ explain select 1 from join t1 on f1 = f3 where f3 = 'aaaa' order by val; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 const PRIMARY PRIMARY 12 const 1 Using index -1 PRIMARY ref key0 key0 13 const 0 Using where; Using filesort +1 PRIMARY ref key0 key0 13 const 0 Using index condition; Using where; Using filesort 2 DERIVED t4 ALL NULL NULL NULL NULL 1 2 DERIVED t2 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) 2 DERIVED t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) diff --git a/mysql-test/main/subselect3_jcl6.result b/mysql-test/main/subselect3_jcl6.result index 291455d821915..e47a820e16e8c 100644 --- a/mysql-test/main/subselect3_jcl6.result +++ b/mysql-test/main/subselect3_jcl6.result @@ -1342,7 +1342,7 @@ insert into t2 select * from t2; explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -1 PRIMARY X hash_ALL NULL #hash#$hj 5 test.t1.a 6 Using where; Start temporary; Using join buffer (flat, BNLH join) +1 PRIMARY X hash_ALL NULL #hash#$hj 10 const,test.t1.a 6 Using where; Start temporary; Using join buffer (flat, BNLH join) 1 PRIMARY Y hash_ALL NULL #hash#$hj 5 test.t1.b 6 Using where; Using join buffer (incremental, BNLH join) 1 PRIMARY Z hash_ALL NULL #hash#$hj 5 test.t1.c 6 Using where; End temporary; Using join buffer (incremental, BNLH join) drop table t0,t1,t2; diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index b347101e25f09..2dc7f4cb650db 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -1542,7 +1542,7 @@ EXPLAIN SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY index_subquery key0 key0 4 const 0 Using where 3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used 4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -1552,7 +1552,7 @@ EXPLAIN SELECT ( 5 ) IN ( SELECT * FROM v1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY index_subquery key0 key0 4 const 0 Using where 3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used 4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -1563,7 +1563,7 @@ EXPLAIN SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY index_subquery key0 key0 5 const 0 Using where 3 DERIVED t1 system NULL NULL NULL NULL 1 4 UNION t2 system NULL NULL NULL NULL 1 NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -1595,7 +1595,7 @@ EXPLAIN SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY index_subquery key0 key0 4 const 0 Using where 3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used 4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -1605,7 +1605,7 @@ EXPLAIN SELECT ( 5 ) IN ( SELECT * FROM v1 ); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY index_subquery key0 key0 4 const 0 Using where 3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used 4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -1616,7 +1616,7 @@ EXPLAIN SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY index_subquery key0 key0 5 const 0 Using where 3 DERIVED t1 system NULL NULL NULL NULL 1 4 UNION t2 system NULL NULL NULL NULL 1 NULL UNION RESULT ALL NULL NULL NULL NULL NULL @@ -1626,7 +1626,7 @@ EXPLAIN SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 system NULL NULL NULL NULL 1 -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY index_subquery key0 key0 5 const 0 Using where 3 DERIVED t1 system NULL NULL NULL NULL 1 4 UNION t2 system NULL NULL NULL NULL 1 NULL UNION RESULT ALL NULL NULL NULL NULL NULL diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result index b048dc54ab6cc..746824048c9aa 100644 --- a/mysql-test/main/subselect_mat.result +++ b/mysql-test/main/subselect_mat.result @@ -2012,7 +2012,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 index NULL c 5 NULL 8 Using where; Using index 2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index -2 MATERIALIZED s1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED s1 hash_ALL NULL #hash#$hj 4 const 8 Using where; Using join buffer (flat, BNLH join) 3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 SELECT a, c FROM t1, t2 WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result index 3e30d3828e587..7ffd6552ee740 100644 --- a/mysql-test/main/subselect_sj_mat.result +++ b/mysql-test/main/subselect_sj_mat.result @@ -2054,7 +2054,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index c c 5 NULL 8 Using index 1 PRIMARY eq_ref distinct_key distinct_key 8 func,func 1 2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index -2 MATERIALIZED s1 hash_ALL c #hash#$hj 5 const 8 Using where; Using join buffer (flat, BNLH join) +2 MATERIALIZED s1 hash_ALL c #hash#$hj 9 const,const 8 Using where; Using join buffer (flat, BNLH join) 3 SUBQUERY t2 ALL NULL NULL NULL NULL 8 SELECT a, c FROM t1, t2 WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2 diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index 4c8f2ac68bb43..6b841afe7a847 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -536,7 +536,7 @@ EXPLAIN SELECT * FROM (SELECT * FROM (SELECT * FROM (SELECT * FROM t1 where id=3) dt3 WHERE id=3) dt2) dt; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 4 const 0 4 PUSHED DERIVED NULL NULL NULL NULL NULL NULL NULL NULL connection slave; CREATE TABLE federated.t10 (a INT,b INT); diff --git a/mysql-test/suite/heap/heap.result b/mysql-test/suite/heap/heap.result index 40795aa51984c..ab13f63d2dbb1 100644 --- a/mysql-test/suite/heap/heap.result +++ b/mysql-test/suite/heap/heap.result @@ -794,7 +794,7 @@ EXPLAIN SELECT col_int_nokey FROM t2 WHERE ('h', 0) NOT IN ( SELECT * FROM v1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 -2 SUBQUERY ALL NULL NULL NULL NULL 2 Using where +2 SUBQUERY ref key0 key0 8 const 0 Using where 3 DERIVED t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where DROP TABLE t1,t2,h1; DROP VIEW v1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 70785f531bb00..cf51a3bf993b9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7203,22 +7203,66 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field) */ if (!field->compression_method() && field->hash_join_is_possible() && - (key_field->optimize & KEY_OPTIMIZE_EQ) && - key_field->val->used_tables()) + (key_field->optimize & KEY_OPTIMIZE_EQ)) { - if (field->can_optimize_hash_join(key_field->cond, key_field->val) != - Data_type_compatibility::OK) - return false; - if (form->is_splittable()) - form->add_splitting_info_for_key_field(key_field); - /* - If a key use is extracted from an equi-join predicate then it is - added not only as a key use for every index whose component can - be evalusted utilizing this key use, but also as a key use for - hash join. Such key uses are marked with a special key number. - */ - if (add_keyuse(keyuse_array, key_field, get_hash_join_key_no(), 0)) - return TRUE; + /* + The KEYUSE entry registered below serves two purposes. For a + regular base table it supplies a component of a hash join key, + which only makes sense when the value comes from another table. + For a materialized derived table that has not yet been created + it also describes a key worth generating on the temp table, and + there a constant equality is just as useful as an equijoin + predicate. + + Grouped derived tables are excluded from the const case because + the optimizer relies on condition pushdown into the underlying + GROUP BY (which also changes row estimates) to handle constant + filters there. Adding a derived key for them would give the + optimizer a second way to apply the same filter, with no benefit. + + A NULL value is excluded. An IS NULL predicate reaches this + point as a NULL literal on the value side. As a hash join key + part it would be compared with equality semantics, and NULL is + never equal to NULL, so every row satisfying the predicate would + be lost. 10.11 has no support for a key part that holds NULL, + so the value is rejected here. The test inspects the item type + rather than evaluating the value, because evaluating a constant + function on the value side would call it an extra time, which is + observable when that function has a side effect. + */ + bool not_derived_grouped= true; + TABLE_LIST *tl= field->table->pos_in_table_list; + if (tl->is_materialized_derived()) + { + for (st_select_lex *sl= tl->derived->first_select(); + sl; + sl= sl->next_select()) + { + if (sl->group_list.elements) + { + not_derived_grouped= false; + break; + } + } + } + bool val_is_null= key_field->val->type() == Item::NULL_ITEM; + if (!val_is_null && + (not_derived_grouped || key_field->val->used_tables())) + { + if (field->can_optimize_hash_join(key_field->cond, key_field->val) != + Data_type_compatibility::OK) + return false; + if (form->is_splittable()) + form->add_splitting_info_for_key_field(key_field); + /* + If a key use is extracted from an equi-join predicate then it is + added not only as a key use for every index whose component can + be evalusted utilizing this key use, but also as a key use for + hash join. Such key uses are marked with a special key number. + */ + if (add_keyuse(keyuse_array, key_field, get_hash_join_key_no(), 0)) + return TRUE; + } } } return FALSE;