List:Commits« Previous MessageNext Message »
From:Roy Lyseng Date:February 13 2012 11:58am
Subject:bzr push into mysql-trunk branch (roy.lyseng:3886 to 3887) WL#5561
View as plain text  
 3887 Roy Lyseng	2012-02-13
      WL#5561 - Enable semi-join transformation with outer join queries
      
      mysql-test/include/join_cache.inc
        Turned off semi-join to preserve plan for an existing test.
      
      mysql-test/include/subquery_sj.inc
        Added new tests for queries that combine outer join with semi-join.
        See HLS of WL#5561 for a basic description of the new tests.
        The tests are grouped according to the "subquery patterns" defined
        in the WL.
      
      mysql-test/r/join_cache_bka.result
      mysql-test/r/join_cache_bka_nixbnl.result
      mysql-test/r/join_cache_bkaunique.result
      mysql-test/r/join_cache_bnl.result
      mysql-test/r/join_cache_nojb.result
        Turned off semi-join to preserve plan for an existing test.
      
      mysql-test/r/subquery_all.result
      mysql-test/r/subquery_all_bka.result
      mysql-test/r/subquery_all_bka_nixbnl.result
      mysql-test/r/subquery_mat_all.result
        Some queries containing inner joins and outer joins that previously
        where executed as "DEPENDENT SUBQUERY" are now transformed
        to semi-joins.
      
      mysql-test/r/subquery_sj_all.result
      mysql-test/r/subquery_sj_all_bka.result
      mysql-test/r/subquery_sj_all_bka_nixbnl.result
      mysql-test/r/subquery_sj_all_bkaunique.result
      mysql-test/r/subquery_sj_dupsweed.result
      mysql-test/r/subquery_sj_dupsweed_bka.result
      mysql-test/r/subquery_sj_dupsweed_bka_nixbnl.result
      mysql-test/r/subquery_sj_dupsweed_bkaunique.result
      mysql-test/r/subquery_sj_firstmatch.result
      mysql-test/r/subquery_sj_firstmatch_bka.result
      mysql-test/r/subquery_sj_firstmatch_bka_nixbnl.result
      mysql-test/r/subquery_sj_firstmatch_bkaunique.result
      mysql-test/r/subquery_sj_loosescan.result
      mysql-test/r/subquery_sj_loosescan_bka.result
      mysql-test/r/subquery_sj_loosescan_bka_nixbnl.result
      mysql-test/r/subquery_sj_loosescan_bkaunique.result
      mysql-test/r/subquery_sj_mat.result
      mysql-test/r/subquery_sj_mat_bka.result
      mysql-test/r/subquery_sj_mat_bka_nixbnl.result
      mysql-test/r/subquery_sj_mat_bkaunique.result
      mysql-test/r/subquery_sj_mat_nosj.result
      mysql-test/r/subquery_sj_none.result
      mysql-test/r/subquery_sj_none_bka.result
      mysql-test/r/subquery_sj_none_bka_nixbnl.result
      mysql-test/r/subquery_sj_none_bkaunique.result
        Contains new results for tests added in WL#5561.
        Some queries containing inner joins and outer joins that previously
        where executed as "DEPENDENT SUBQUERY" are now transformed
        to semi-joins.
        Some results are reordered because of the new plans.
      
      mysql-test/r/subselect_innodb.result
        Some plans changed because of semi-join transformation.
      
      mysql-test/r/type_time.result
        Turned off semi-join to preserve plan for an existing test.
      
      mysql-test/r/view.result
        One result reordering because plan was changed.
      
      mysql-test/suite/opt_trace/r/general_no_prot_all.result
      mysql-test/suite/opt_trace/r/general_ps_prot_all.result
        Changed optimizer trace because plans were changed.
      
      mysql-test/t/type_time.test
        Turned off semi-join to preserve plan for an existing test.
      
      sql/item_func.cc
        Item_func::fix_fields() was called for a previously fixed item.
        In order to avoid having yet another test in the caller, the
        DBUG_ASSERT(fixed == 0) was removed and fix_fields() will instead
        exit early when the item is already fixed.
        See LLD section 2.1.
      
      sql/sql_executor.cc
        do_sj_dups_weedout(): Corrected bug in NULL handling when writing
        duplicate weedout row.
        See LLD section 2.7.
        evaluate_null_complemented_join_record(): Made sure that
        duplicate weedout table is properly reset also when we add a
        null complemented row.
        See LLD section 2.6.
      
      sql/sql_optimizer.cc
        record_semijoin_nests() was split out from simplify_joins(), because
        sometimes a semi-join nest was recorded twice.
        Simplifying the complex simplify_joins() (sic) was also reasonable.
        See LLD section 2.9.
        semijoin_types_allow_materialization(): Small interface change.
        optimize_semijoin_nests(): as a short-term measure, disallow
        materialization when there are dependencies to the outer tables.
        See LLD section 2.2.
        build_bitmap_for_nested_join(): Updated to use the new nj_xxx fields.
        Record tables belonging in semi-join nests in the embedding outer join
        nest (if any).
        See LLD section 2.5.
        convert_subquery_to_semijoin(): Removed disabling of semi-join
        transformation when there are outer joins in the outer query.
        See LLD chapter 1.
        convert_subquery_to_semijoin(): Made changes to on_expr to be
        reflected in the permanent data as well (prep_on_expr).
        See LLD section 2.4.
        make_outerjoin_info(): Updated to use the new nj_xxx fields.
        See LLD section 2.5.
      
      sql/sql_planner.cc
        check_interleaving_with_nj(): Updated to ignore join nests without
        nj_map information, and use new nj_xxx fields.
        backout_nj_sj_state(): Updated to use new nj_xxx fields.
      
      sql/sql_select.cc
        setup_semijoin_dups_elimination(): Code that assures that duplicate
        weedout extends across all tables of an outer join operation.
        See LLD section 2.8.
        setup_join_buffering(): Eliminated use of join cache when there
        is an outer join operation and first match strategy is used.
      
      sql/table.cc
        When resolving a view, call fix_fields() on the view's WHERE
        condition only once. This fix_fields() call enables some needed
        initial transformations to the condition, and is prerequisite to
        separate out the view check option. However for subsequent
        executions, the view condition is part of complete query condition,
        and will be resolved as part of this. There was a crash because of
        this, because fix_fields() did non-permanent transformations on
        subquery transformed to semi-join on second execution.
      
      sql/table.h
        Replaced fields used to analyze nested joins with new ones:
        nj_total, nj_counter, nj_map.
        See LLD section 2.5.

    removed:
      mysql-test/suite/rpl/t/rpl_mixed_crash_safe-slave.opt.THIS
    modified:
      mysql-test/include/join_cache.inc
      mysql-test/include/subquery_sj.inc
      mysql-test/r/join_cache_bka.result
      mysql-test/r/join_cache_bka_nixbnl.result
      mysql-test/r/join_cache_bkaunique.result
      mysql-test/r/join_cache_bnl.result
      mysql-test/r/join_cache_nojb.result
      mysql-test/r/subquery_all.result
      mysql-test/r/subquery_all_bka.result
      mysql-test/r/subquery_all_bka_nixbnl.result
      mysql-test/r/subquery_mat_all.result
      mysql-test/r/subquery_sj_all.result
      mysql-test/r/subquery_sj_all_bka.result
      mysql-test/r/subquery_sj_all_bka_nixbnl.result
      mysql-test/r/subquery_sj_all_bkaunique.result
      mysql-test/r/subquery_sj_dupsweed.result
      mysql-test/r/subquery_sj_dupsweed_bka.result
      mysql-test/r/subquery_sj_dupsweed_bka_nixbnl.result
      mysql-test/r/subquery_sj_dupsweed_bkaunique.result
      mysql-test/r/subquery_sj_firstmatch.result
      mysql-test/r/subquery_sj_firstmatch_bka.result
      mysql-test/r/subquery_sj_firstmatch_bka_nixbnl.result
      mysql-test/r/subquery_sj_firstmatch_bkaunique.result
      mysql-test/r/subquery_sj_loosescan.result
      mysql-test/r/subquery_sj_loosescan_bka.result
      mysql-test/r/subquery_sj_loosescan_bka_nixbnl.result
      mysql-test/r/subquery_sj_loosescan_bkaunique.result
      mysql-test/r/subquery_sj_mat.result
      mysql-test/r/subquery_sj_mat_bka.result
      mysql-test/r/subquery_sj_mat_bka_nixbnl.result
      mysql-test/r/subquery_sj_mat_bkaunique.result
      mysql-test/r/subquery_sj_mat_nosj.result
      mysql-test/r/subquery_sj_none.result
      mysql-test/r/subquery_sj_none_bka.result
      mysql-test/r/subquery_sj_none_bka_nixbnl.result
      mysql-test/r/subquery_sj_none_bkaunique.result
      mysql-test/r/subselect_innodb.result
      mysql-test/r/type_time.result
      mysql-test/r/view.result
      mysql-test/suite/opt_trace/r/general_no_prot_all.result
      mysql-test/suite/opt_trace/r/general_ps_prot_all.result
      mysql-test/t/type_time.test
      sql/item_func.cc
      sql/sql_executor.cc
      sql/sql_optimizer.cc
      sql/sql_planner.cc
      sql/sql_select.cc
      sql/table.cc
      sql/table.h
 3886 Gopal Shankar	2012-02-13
      Bug#13586314 - RUNTIME - HIBISCUS: ISSUE DEPRECATION
                     WARNING FOR LOW_PRIORITY MODIFIER
      
      As of 5.5.3, the LOW_PRIORITY modifier for
      'LOCK TABLES tbl_name LOW_PRIORITY WRITE' command has no
      effect. This patch adds deprecation warning for above command,
      based on a decision made as part of WL#6101.

    modified:
      mysql-test/r/lock.result
      mysql-test/t/lock.test
      sql/sql_yacc.yy
=== modified file 'mysql-test/include/join_cache.inc'
--- a/mysql-test/include/join_cache.inc	2012-02-08 15:25:17 +0000
+++ b/mysql-test/include/join_cache.inc	2012-02-13 11:57:09 +0000
@@ -2015,6 +2015,9 @@ CREATE TABLE t2 (
 INSERT INTO t2 VALUES (9, '2002-08-25 20:35:06', 'e'),
                       (9, '2002-08-25 20:35:06', 'e');
 
+set @optimizer_switch_saved=@@session.optimizer_switch;
+set @@session.optimizer_switch='semijoin=off';
+
 let $query=SELECT PARENT1.col_varchar_key
 FROM t2 AS PARENT1 LEFT JOIN t1 USING (col_int_nokey)
 WHERE PARENT1.col_varchar_key IN
@@ -2025,4 +2028,6 @@ WHERE PARENT1.col_varchar_key IN
 eval EXPLAIN $query;
 eval $query;
 
+set @@session.optimizer_switch=@optimizer_switch_saved;
+
 DROP TABLE t1,t2;

=== modified file 'mysql-test/include/subquery_sj.inc'
--- a/mysql-test/include/subquery_sj.inc	2012-01-31 11:19:25 +0000
+++ b/mysql-test/include/subquery_sj.inc	2012-02-13 11:57:09 +0000
@@ -1088,7 +1088,405 @@ where a1 in (select group_concat(b1) fro
 
 drop table t1_1025, t2_1025, t3_1025;
 
+--echo #
+--echo # WL#5561: Enable semi join transformation with outer join.
+--echo #
+
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+
+--echo # Test cases, Subquery Pattern 1
+
+--echo # Example SQ1.1:
+
+let $query=
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ1.2:
+
+let $query=
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ1.3:
+
+let $query=
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # More test cases
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+         LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+         LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+         LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+         LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+         LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+         LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+
+--echo # Test cases, Subquery Pattern 2
+
+--echo # Example SQ2.1:
+
+let $query=
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ2.2:
+
+let $query=
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+                                 AND ot2.a IN (SELECT a FROM it3);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # More test cases
+
+--sorted_result
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+                                 AND ot2.a IN (SELECT a+0 FROM it3);
 
+--sorted_result
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+         JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+
+--echo # Test cases, Subquery Pattern 3
+
+--echo # Example SQ3.1:
+
+let $query=
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ3.2:
+
+let $query=
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ3.3
+
+let $query=
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+                                      AND ot2.a IN (SELECT a FROM it2);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ3.4
+
+let $query=
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+                         (ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+                                            FROM it1 JOIN it2 ON it1.a=it2.a);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # More test cases
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+                                        AND ot2.a IN (SELECT a+0 FROM it2);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+                         (ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+                                            FROM it1 JOIN it2 ON it1.a=it2.a);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+         LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+
+--sorted_result
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+         LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+
+--echo # Test cases, Subquery Pattern 4
+
+--echo # Example SQ4.1:
+
+let $query=
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ4.2:
+
+let $query=
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ4.3:
+
+let $query=
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # Example SQ4.4:
+
+let $query=
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+eval explain $query;
+--sorted_result
+eval $query;
+
+--echo # More test cases
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+     LEFT JOIN
+       ot1 AS ot4
+     ON ot2.a=ot4.a;
+
+--sorted_result
+SELECT *
+FROM   ot1
+     LEFT JOIN
+       (ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+            LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+     ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+
+--echo # End of WL#5561
 
 --echo #
 --echo # Bug#48868: Left outer join in subquery causes segmentation fault in
@@ -1842,6 +2240,7 @@ SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 
+--sorted_result
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 
@@ -3608,9 +4007,12 @@ FROM   ot1
      ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 
 eval explain $query;
+--sorted_result
 eval $query;
 eval prepare s from '$query';
+--sorted_result
 execute s;
+--sorted_result
 execute s;
 deallocate prepare s;
 
@@ -3908,6 +4310,7 @@ WHERE (grandparent1.col_varchar_key) IN
                 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 
 eval EXPLAIN $query;
+--sorted_result
 eval $query;
 
 DROP TABLE t1, t2;

=== modified file 'mysql-test/r/join_cache_bka.result'
--- a/mysql-test/r/join_cache_bka.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/join_cache_bka.result	2012-02-13 11:57:09 +0000
@@ -2717,6 +2717,8 @@ KEY col_varchar_key (col_varchar_key)
 );
 INSERT INTO t2 VALUES (9, '2002-08-25 20:35:06', 'e'),
 (9, '2002-08-25 20:35:06', 'e');
+set @optimizer_switch_saved=@@session.optimizer_switch;
+set @@session.optimizer_switch='semijoin=off';
 EXPLAIN SELECT PARENT1.col_varchar_key
 FROM t2 AS PARENT1 LEFT JOIN t1 USING (col_int_nokey)
 WHERE PARENT1.col_varchar_key IN
@@ -2736,5 +2738,6 @@ WHERE PARENT1.col_datetime_nokey IS NULL
 AND t1.col_int_nokey IS NULL )
 ;
 col_varchar_key
+set @@session.optimizer_switch=@optimizer_switch_saved;
 DROP TABLE t1,t2;
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_bka_nixbnl.result'
--- a/mysql-test/r/join_cache_bka_nixbnl.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/join_cache_bka_nixbnl.result	2012-02-13 11:57:09 +0000
@@ -2717,6 +2717,8 @@ KEY col_varchar_key (col_varchar_key)
 );
 INSERT INTO t2 VALUES (9, '2002-08-25 20:35:06', 'e'),
 (9, '2002-08-25 20:35:06', 'e');
+set @optimizer_switch_saved=@@session.optimizer_switch;
+set @@session.optimizer_switch='semijoin=off';
 EXPLAIN SELECT PARENT1.col_varchar_key
 FROM t2 AS PARENT1 LEFT JOIN t1 USING (col_int_nokey)
 WHERE PARENT1.col_varchar_key IN
@@ -2736,5 +2738,6 @@ WHERE PARENT1.col_datetime_nokey IS NULL
 AND t1.col_int_nokey IS NULL )
 ;
 col_varchar_key
+set @@session.optimizer_switch=@optimizer_switch_saved;
 DROP TABLE t1,t2;
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_bkaunique.result'
--- a/mysql-test/r/join_cache_bkaunique.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/join_cache_bkaunique.result	2012-02-13 11:57:09 +0000
@@ -2718,6 +2718,8 @@ KEY col_varchar_key (col_varchar_key)
 );
 INSERT INTO t2 VALUES (9, '2002-08-25 20:35:06', 'e'),
 (9, '2002-08-25 20:35:06', 'e');
+set @optimizer_switch_saved=@@session.optimizer_switch;
+set @@session.optimizer_switch='semijoin=off';
 EXPLAIN SELECT PARENT1.col_varchar_key
 FROM t2 AS PARENT1 LEFT JOIN t1 USING (col_int_nokey)
 WHERE PARENT1.col_varchar_key IN
@@ -2737,5 +2739,6 @@ WHERE PARENT1.col_datetime_nokey IS NULL
 AND t1.col_int_nokey IS NULL )
 ;
 col_varchar_key
+set @@session.optimizer_switch=@optimizer_switch_saved;
 DROP TABLE t1,t2;
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_bnl.result'
--- a/mysql-test/r/join_cache_bnl.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/join_cache_bnl.result	2012-02-13 11:57:09 +0000
@@ -2718,6 +2718,8 @@ KEY col_varchar_key (col_varchar_key)
 );
 INSERT INTO t2 VALUES (9, '2002-08-25 20:35:06', 'e'),
 (9, '2002-08-25 20:35:06', 'e');
+set @optimizer_switch_saved=@@session.optimizer_switch;
+set @@session.optimizer_switch='semijoin=off';
 EXPLAIN SELECT PARENT1.col_varchar_key
 FROM t2 AS PARENT1 LEFT JOIN t1 USING (col_int_nokey)
 WHERE PARENT1.col_varchar_key IN
@@ -2737,5 +2739,6 @@ WHERE PARENT1.col_datetime_nokey IS NULL
 AND t1.col_int_nokey IS NULL )
 ;
 col_varchar_key
+set @@session.optimizer_switch=@optimizer_switch_saved;
 DROP TABLE t1,t2;
 set optimizer_switch = default;

=== modified file 'mysql-test/r/join_cache_nojb.result'
--- a/mysql-test/r/join_cache_nojb.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/join_cache_nojb.result	2012-02-13 11:57:09 +0000
@@ -2718,6 +2718,8 @@ KEY col_varchar_key (col_varchar_key)
 );
 INSERT INTO t2 VALUES (9, '2002-08-25 20:35:06', 'e'),
 (9, '2002-08-25 20:35:06', 'e');
+set @optimizer_switch_saved=@@session.optimizer_switch;
+set @@session.optimizer_switch='semijoin=off';
 EXPLAIN SELECT PARENT1.col_varchar_key
 FROM t2 AS PARENT1 LEFT JOIN t1 USING (col_int_nokey)
 WHERE PARENT1.col_varchar_key IN
@@ -2737,5 +2739,6 @@ WHERE PARENT1.col_datetime_nokey IS NULL
 AND t1.col_int_nokey IS NULL )
 ;
 col_varchar_key
+set @@session.optimizer_switch=@optimizer_switch_saved;
 DROP TABLE t1,t2;
 set optimizer_switch = default;

=== modified file 'mysql-test/r/subquery_all.result'
--- a/mysql-test/r/subquery_all.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_all.result	2012-02-13 11:57:09 +0000
@@ -6864,14 +6864,14 @@ AND sq2_alias1.col_varchar_key > alias1.
 )
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Start temporary
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-2	DEPENDENT SUBQUERY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; End temporary; Using join buffer (Block Nested Loop)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #2 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #2 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#2 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`test`.`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `test`.`t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `test`.`t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`test`.`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `test`.`t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `test`.`t1`.`col_varchar_key`))
 SELECT alias2.col_varchar_nokey
 FROM v1 AS alias1
 RIGHT JOIN t1 AS alias2 ON 1
@@ -6908,14 +6908,14 @@ AND sq2_alias1.col_varchar_key > alias1.
 ;
 EXPLAIN EXTENDED SELECT * FROM v2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Start temporary
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index; Using join buffer (Block Nested Loop)
-3	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-3	DEPENDENT SUBQUERY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; End temporary; Using join buffer (Block Nested Loop)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #3 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #3 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#3 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`))
 SELECT * FROM v2;
 col_varchar_nokey
 d
@@ -6939,14 +6939,14 @@ WHERE sq2_alias1.pk != alias1.col_int_ke
 AND sq2_alias1.col_varchar_key > alias1.col_varchar_key
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Start temporary
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-2	DEPENDENT SUBQUERY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; End temporary; Using join buffer (Block Nested Loop)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #2 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #2 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#2 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`))
 SELECT alias2.col_varchar_nokey
 FROM t1 AS alias2
 LEFT JOIN v1 AS alias1 ON 1

=== modified file 'mysql-test/r/subquery_all_bka.result'
--- a/mysql-test/r/subquery_all_bka.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_all_bka.result	2012-02-13 11:57:09 +0000
@@ -6865,14 +6865,14 @@ AND sq2_alias1.col_varchar_key > alias1.
 )
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Start temporary
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-2	DEPENDENT SUBQUERY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; End temporary; Using join buffer (Block Nested Loop)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #2 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #2 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#2 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`test`.`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `test`.`t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `test`.`t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`test`.`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `test`.`t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `test`.`t1`.`col_varchar_key`))
 SELECT alias2.col_varchar_nokey
 FROM v1 AS alias1
 RIGHT JOIN t1 AS alias2 ON 1
@@ -6909,14 +6909,14 @@ AND sq2_alias1.col_varchar_key > alias1.
 ;
 EXPLAIN EXTENDED SELECT * FROM v2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Start temporary
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index; Using join buffer (Block Nested Loop)
-3	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-3	DEPENDENT SUBQUERY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; End temporary; Using join buffer (Block Nested Loop)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #3 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #3 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#3 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`))
 SELECT * FROM v2;
 col_varchar_nokey
 d
@@ -6940,14 +6940,14 @@ WHERE sq2_alias1.pk != alias1.col_int_ke
 AND sq2_alias1.col_varchar_key > alias1.col_varchar_key
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Start temporary
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-2	DEPENDENT SUBQUERY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	index	col_int_key	col_int_key	4	NULL	5	80.00	Using where; Using index; End temporary; Using join buffer (Block Nested Loop)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #2 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #2 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#2 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`))
 SELECT alias2.col_varchar_nokey
 FROM t1 AS alias2
 LEFT JOIN v1 AS alias1 ON 1

=== modified file 'mysql-test/r/subquery_all_bka_nixbnl.result'
--- a/mysql-test/r/subquery_all_bka_nixbnl.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_all_bka_nixbnl.result	2012-02-13 11:57:09 +0000
@@ -6865,14 +6865,14 @@ AND sq2_alias1.col_varchar_key > alias1.
 )
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-2	DEPENDENT SUBQUERY	sq2_alias2	ref	col_int_key	col_int_key	4	test.t1.pk	2	100.00	Using index
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	ref	col_int_key	col_int_key	4	func	2	100.00	Using where; Using index; FirstMatch(t1)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #2 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #2 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#2 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`test`.`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `test`.`t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `test`.`t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`test`.`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `test`.`t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `test`.`t1`.`col_varchar_key`))
 SELECT alias2.col_varchar_nokey
 FROM v1 AS alias1
 RIGHT JOIN t1 AS alias2 ON 1
@@ -6909,14 +6909,14 @@ AND sq2_alias1.col_varchar_key > alias1.
 ;
 EXPLAIN EXTENDED SELECT * FROM v2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index
-3	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-3	DEPENDENT SUBQUERY	sq2_alias2	ref	col_int_key	col_int_key	4	test.t1.pk	2	100.00	Using index
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	ref	col_int_key	col_int_key	4	func	2	100.00	Using where; Using index; FirstMatch(t1)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #3 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #3 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#3 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`))
 SELECT * FROM v2;
 col_varchar_nokey
 d
@@ -6940,14 +6940,14 @@ WHERE sq2_alias1.pk != alias1.col_int_ke
 AND sq2_alias1.col_varchar_key > alias1.col_varchar_key
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	alias2	ALL	NULL	NULL	NULL	NULL	5	100.00	
+1	PRIMARY	alias2	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	
 1	PRIMARY	t1	index	NULL	col_varchar_key	7	NULL	5	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Using where
-2	DEPENDENT SUBQUERY	sq2_alias2	ref	col_int_key	col_int_key	4	test.t1.pk	2	100.00	Using index
+1	PRIMARY	t1	ALL	col_varchar_key	NULL	NULL	NULL	5	100.00	Range checked for each record (index map: 0x4)
+1	PRIMARY	sq2_alias2	ref	col_int_key	col_int_key	4	func	2	100.00	Using where; Using index; FirstMatch(t1)
 Warnings:
 Note	1276	Field or reference 'alias1.col_int_key' of SELECT #2 was resolved in SELECT #1
 Note	1276	Field or reference 'alias1.col_varchar_key' of SELECT #2 was resolved in SELECT #1
-Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` left join (`test`.`t1`) on(1) where <in_optimizer>(`test`.`alias2`.`col_varchar_key`,<exists>(/* select#2 */ select 1 from `test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`)) where ((`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`) and (<cache>(`test`.`alias2`.`col_varchar_key`) = `test`.`t1`.`col_varchar_nokey`))))
+Note	1003	/* select#1 */ select `test`.`alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from `test`.`t1` `alias2` semi join (`test`.`t1` left join `test`.`t1` `sq2_alias2` on((`sq2_alias2`.`col_int_key` = `test`.`t1`.`pk`))) left join (`test`.`t1`) on(1) where ((`test`.`t1`.`col_varchar_nokey` = `test`.`alias2`.`col_varchar_key`) and (`test`.`t1`.`pk` <> `t1`.`col_int_key`) and (`test`.`t1`.`col_varchar_key` > `t1`.`col_varchar_key`))
 SELECT alias2.col_varchar_nokey
 FROM t1 AS alias2
 LEFT JOIN v1 AS alias1 ON 1

=== modified file 'mysql-test/r/subquery_mat_all.result'
--- a/mysql-test/r/subquery_mat_all.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_mat_all.result	2012-02-13 11:57:09 +0000
@@ -810,8 +810,8 @@ GROUP BY t3i
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	system	NULL	NULL	NULL	NULL	1	
 1	PRIMARY	t4	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch(t2); Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Start materialize
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; End materialize; Using join buffer (Block Nested Loop)
 DROP TABLE t1,t2,t3,t4;
 #
 # BUG#46680 - Assertion failed in file item_subselect.cc, 
@@ -973,8 +973,8 @@ EXPLAIN
 SELECT i, j FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
 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	system	NULL	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	no matching row in const table
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	0	Using where; Start temporary
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	1	Using where; End temporary
 SELECT i, j FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
 i	j
 10	NULL
@@ -1119,7 +1119,6 @@ explain SELECT * FROM t1 JOIN t2 USING (
 WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
-2	DEPENDENT SUBQUERY	t1	system	PRIMARY	NULL	NULL	NULL	1	
 SELECT * FROM t1 JOIN t2 USING (f1)
 WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
 f1	pk	pk
@@ -1371,9 +1370,9 @@ where (t2.a,t2.a) in (select a,a from t2
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where; FirstMatch(t2); Using join buffer (Block Nested Loop)
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`a`),<exists>(/* select#2 */ select `test`.`t3`.`a`,`test`.`t3`.`a` from `test`.`t2` `t3` where ((<cache>(`test`.`t2`.`a`) = `test`.`t3`.`a`) and (<cache>(`test`.`t2`.`a`) = `test`.`t3`.`a`)))) and ((`test`.`t1`.`a` + `test`.`t2`.`a`) = 3))
+Note	1003	/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2` `t3`) join `test`.`t2` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((`test`.`t1`.`a` + `test`.`t2`.`a`) = 3))
 select t1.a, t2.a
 from t1 join t2 on t1.a+t2.a=3
 where (t2.a,t2.a) in (select a,a from t2 as t3);

=== modified file 'mysql-test/r/subquery_sj_all.result'
--- a/mysql-test/r/subquery_sj_all.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_all.result	2012-02-13 11:57:09 +0000
@@ -171,20 +171,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3887,6 +3887,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4617,23 +5285,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5546,8 +6214,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6242,9 +6910,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6252,12 +6920,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6267,22 +6935,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6577,11 +7245,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6592,21 +7260,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7137,9 +7805,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7191,10 +7859,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a); Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7307,11 +7975,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End materialize; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7607,10 +8275,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_all_bka.result'
--- a/mysql-test/r/subquery_sj_all_bka.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_all_bka.result	2012-02-13 11:57:09 +0000
@@ -172,20 +172,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,23 +5286,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5547,8 +6215,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,9 +6911,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6253,12 +6921,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6268,22 +6936,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize; Using join buffer (Batched Key Access)
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	Using join buffer (Batched Key Access)
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; Using join buffer (Batched Key Access)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a); Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End materialize; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_all_bka_nixbnl.result'
--- a/mysql-test/r/subquery_sj_all_bka_nixbnl.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_all_bka_nixbnl.result	2012-02-13 11:57:09 +0000
@@ -173,19 +173,19 @@ select * from t1 left join (t2 A, t2 B) 
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,8 +5286,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
@@ -4633,8 +5301,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,7 +6216,7 @@ select * from t1 left join t2 on (t2.a= 
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,9 +6911,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize; Using join buffer (Batched Key Access)
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	Using join buffer (Batched Key Access)
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; Using join buffer (Batched Key Access)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
 1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize; Using join buffer (Batched Key Access)
+1	PRIMARY	grandparent1	ref	col_int_key,col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	1	Using index condition; Using join buffer (Batched Key Access)
 1	PRIMARY	grandparent2	ref	col_int_key	col_int_key	5	test.grandparent1.col_int_key	2	Using index
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; Using join buffer (Batched Key Access)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
 1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_all_bkaunique.result'
--- a/mysql-test/r/subquery_sj_all_bkaunique.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_all_bkaunique.result	2012-02-13 11:57:09 +0000
@@ -173,20 +173,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3889,6 +3889,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4619,23 +5287,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,8 +6216,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6244,9 +6912,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6254,12 +6922,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6269,22 +6937,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6579,11 +7247,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize; Using join buffer (Batched Key Access (unique))
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	Using join buffer (Batched Key Access (unique))
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; Using join buffer (Batched Key Access (unique))
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6594,21 +7262,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7139,9 +7807,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7193,10 +7861,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a); Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7309,11 +7977,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End materialize; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7609,10 +8277,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_dupsweed.result'
--- a/mysql-test/r/subquery_sj_dupsweed.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_dupsweed.result	2012-02-13 11:57:09 +0000
@@ -170,20 +170,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3886,6 +3886,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Start temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4616,23 +5284,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5545,8 +6213,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6240,10 +6908,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6251,12 +6919,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6266,22 +6934,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6576,11 +7244,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6591,21 +7259,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7136,9 +7804,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7190,10 +7858,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7306,11 +7974,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7606,10 +8274,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_dupsweed_bka.result'
--- a/mysql-test/r/subquery_sj_dupsweed_bka.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_dupsweed_bka.result	2012-02-13 11:57:09 +0000
@@ -171,20 +171,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3887,6 +3887,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Start temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4617,23 +5285,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5546,8 +6214,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6241,10 +6909,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6252,12 +6920,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6267,22 +6935,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6577,11 +7245,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6592,21 +7260,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7137,9 +7805,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7191,10 +7859,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7307,11 +7975,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7607,10 +8275,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_dupsweed_bka_nixbnl.result'
--- a/mysql-test/r/subquery_sj_dupsweed_bka_nixbnl.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_dupsweed_bka_nixbnl.result	2012-02-13 11:57:09 +0000
@@ -172,19 +172,19 @@ select * from t1 left join (t2 A, t2 B) 
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3887,6 +3887,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Start temporary; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4617,8 +5285,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
@@ -4632,8 +5300,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5547,7 +6215,7 @@ select * from t1 left join t2 on (t2.a= 
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6242,9 +6910,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6577,11 +7245,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6592,21 +7260,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7137,9 +7805,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
 1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7191,10 +7859,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7307,11 +7975,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_int_key,col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	1	Using where; End temporary
 1	PRIMARY	grandparent2	ref	col_int_key	col_int_key	5	test.grandparent1.col_int_key	2	Using index
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7607,10 +8275,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
 1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_dupsweed_bkaunique.result'
--- a/mysql-test/r/subquery_sj_dupsweed_bkaunique.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_dupsweed_bkaunique.result	2012-02-13 11:57:09 +0000
@@ -172,20 +172,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Start temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,23 +5286,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5547,8 +6215,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6242,10 +6910,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6253,12 +6921,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6268,22 +6936,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_firstmatch.result'
--- a/mysql-test/r/subquery_sj_firstmatch.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_firstmatch.result	2012-02-13 11:57:09 +0000
@@ -171,20 +171,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3887,6 +3887,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2); Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1); Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1); Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4617,23 +5285,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5546,8 +6214,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6242,9 +6910,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6252,12 +6920,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6267,22 +6935,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6577,11 +7245,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6592,21 +7260,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7137,9 +7805,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7191,10 +7859,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a); Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7307,11 +7975,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7607,10 +8275,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_firstmatch_bka.result'
--- a/mysql-test/r/subquery_sj_firstmatch_bka.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_firstmatch_bka.result	2012-02-13 11:57:09 +0000
@@ -172,20 +172,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2); Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1); Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1); Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,23 +5286,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5547,8 +6215,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,9 +6911,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6253,12 +6921,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6268,22 +6936,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a); Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_firstmatch_bka_nixbnl.result'
--- a/mysql-test/r/subquery_sj_firstmatch_bka_nixbnl.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_firstmatch_bka_nixbnl.result	2012-02-13 11:57:09 +0000
@@ -173,19 +173,19 @@ select * from t1 left join (t2 A, t2 B) 
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,8 +5286,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
@@ -4633,8 +5301,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,7 +6216,7 @@ select * from t1 left join t2 on (t2.a= 
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,9 +6911,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
 1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_int_key,col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	1	Using where; End temporary
 1	PRIMARY	grandparent2	ref	col_int_key	col_int_key	5	test.grandparent1.col_int_key	2	Using index
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
 1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_firstmatch_bkaunique.result'
--- a/mysql-test/r/subquery_sj_firstmatch_bkaunique.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_firstmatch_bkaunique.result	2012-02-13 11:57:09 +0000
@@ -173,20 +173,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3889,6 +3889,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2); Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(ot2)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1); Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1); Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4619,23 +5287,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,8 +6216,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6244,9 +6912,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; FirstMatch(ot1)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6254,12 +6922,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6269,22 +6937,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6579,11 +7247,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6594,21 +7262,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7139,9 +7807,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; FirstMatch
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7193,10 +7861,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t1a); Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; FirstMatch(t2)
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7309,11 +7977,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7609,10 +8277,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start temporary
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_loosescan.result'
--- a/mysql-test/r/subquery_sj_loosescan.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_loosescan.result	2012-02-13 11:57:09 +0000
@@ -171,20 +171,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3887,6 +3887,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Start temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4617,23 +5285,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5546,8 +6214,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6241,10 +6909,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6252,12 +6920,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6267,22 +6935,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6577,11 +7245,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6592,21 +7260,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7137,9 +7805,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7191,10 +7859,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7307,11 +7975,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7607,10 +8275,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_loosescan_bka.result'
--- a/mysql-test/r/subquery_sj_loosescan_bka.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_loosescan_bka.result	2012-02-13 11:57:09 +0000
@@ -172,20 +172,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Start temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,23 +5286,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5547,8 +6215,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6242,10 +6910,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6253,12 +6921,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6268,22 +6936,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_loosescan_bka_nixbnl.result'
--- a/mysql-test/r/subquery_sj_loosescan_bka_nixbnl.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_loosescan_bka_nixbnl.result	2012-02-13 11:57:09 +0000
@@ -173,19 +173,19 @@ select * from t1 left join (t2 A, t2 B) 
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Start temporary; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,8 +5286,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
@@ -4633,8 +5301,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,7 +6216,7 @@ select * from t1 left join t2 on (t2.a= 
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,9 +6911,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
 1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_int_key,col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	1	Using where; End temporary
 1	PRIMARY	grandparent2	ref	col_int_key	col_int_key	5	test.grandparent1.col_int_key	2	Using index
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
 1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_loosescan_bkaunique.result'
--- a/mysql-test/r/subquery_sj_loosescan_bkaunique.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_loosescan_bkaunique.result	2012-02-13 11:57:09 +0000
@@ -173,20 +173,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3889,6 +3889,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Start temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4619,23 +5287,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,8 +6216,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,10 +6911,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6254,12 +6922,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6269,22 +6937,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6579,11 +7247,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	End temporary
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End temporary
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6594,21 +7262,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7139,9 +7807,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Start temporary; End temporary
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7193,10 +7861,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7309,11 +7977,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7609,10 +8277,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; LooseScan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; FirstMatch(t2)
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_mat.result'
--- a/mysql-test/r/subquery_sj_mat.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_mat.result	2012-02-13 11:57:09 +0000
@@ -171,20 +171,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3887,6 +3887,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4617,23 +5285,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5546,8 +6214,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6241,10 +6909,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6252,12 +6920,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6267,22 +6935,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6577,11 +7245,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6592,21 +7260,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7137,9 +7805,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Materialize
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7191,10 +7859,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Materialize
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7307,11 +7975,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End materialize; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7607,10 +8275,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start materialize; Scan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; End materialize
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_mat_bka.result'
--- a/mysql-test/r/subquery_sj_mat_bka.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_mat_bka.result	2012-02-13 11:57:09 +0000
@@ -172,20 +172,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,23 +5286,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5547,8 +6215,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6242,10 +6910,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6253,12 +6921,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6268,22 +6936,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Materialize
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Materialize
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End materialize; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start materialize; Scan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; End materialize
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_mat_bka_nixbnl.result'
--- a/mysql-test/r/subquery_sj_mat_bka_nixbnl.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_mat_bka_nixbnl.result	2012-02-13 11:57:09 +0000
@@ -173,19 +173,19 @@ select * from t1 left join (t2 A, t2 B) 
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3888,6 +3888,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Start temporary; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4618,8 +5286,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
@@ -4633,8 +5301,8 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,7 +6216,7 @@ select * from t1 left join t2 on (t2.a= 
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,9 +6911,9 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start temporary; End temporary
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
 1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6578,11 +7246,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6593,21 +7261,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7138,9 +7806,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Materialize
 1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7192,10 +7860,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Start temporary; End temporary
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Materialize
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7308,11 +7976,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize
+1	PRIMARY	grandparent1	ref	col_int_key,col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	1	Using where
 1	PRIMARY	grandparent2	ref	col_int_key	col_int_key	5	test.grandparent1.col_int_key	2	Using index
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7608,10 +8276,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
 1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start materialize; Scan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; End materialize
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_mat_bkaunique.result'
--- a/mysql-test/r/subquery_sj_mat_bkaunique.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_mat_bkaunique.result	2012-02-13 11:57:09 +0000
@@ -173,20 +173,20 @@ explAin extended
 select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	A	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	B	ALL	NULL	NULL	NULL	NULL	3	100.00	
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.B.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`B`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`B`.`A` = `test`.`t10`.`pk`))) where 1
 t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
 explAin extended
 select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
 id	select_type	tABle	type	possiBle_keys	key	key_len	ref	rows	filtered	ExtrA
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join Buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t10	unique_suBquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where
+1	PRIMARY	t10	eq_ref	PRIMARY	PRIMARY	4	test.t2.A	1	100.00	Using index
 Warnings:
-Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t2`.`A`,<exists>(<primAry_index_lookup>(<cAche>(`test`.`t2`.`A`) in t10 on PRIMARY))))) where 1
+Note	1003	/* select#1 */ select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join (`test`.`t10` join `test`.`t2`) on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And 1 And (`test`.`t2`.`A` = `test`.`t10`.`pk`))) where 1
 we shouldn't flatten if we're going to get a join of > MAX_TABLES.
 explain select * from 
 t1 s00, t1 s01,  t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -3889,6 +3889,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Start temporary
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Materialize; Scan
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Materialize
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Materialize
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4619,23 +5287,23 @@ FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
 WHERE t1field IN (SELECT v1field FROM v1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
-1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using where; Using index
-4	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	a	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
 CREATE PROCEDURE p1() 
 BEGIN 
 SELECT t1field
@@ -5548,8 +6216,8 @@ explain 
 select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using index
 drop table t0, t1, t2, t3;
 create table t1 (a int not null);
 drop procedure if exists p1|
@@ -6243,10 +6911,10 @@ LEFT JOIN
 (ot2 JOIN ot3 on ot2.a=ot3.a)
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
-1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
-1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Start temporary
+1	PRIMARY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT *
 FROM   ot1
 LEFT JOIN
@@ -6254,12 +6922,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6269,22 +6937,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6579,11 +7247,11 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	NULL	NULL	NULL	NULL	15	Using where
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where; End materialize
+1	PRIMARY	grandparent1	ref	col_varchar_key	col_varchar_key	4	test.parent1.col_varchar_nokey	2	
 1	PRIMARY	grandparent2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	15	Using where; Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ref	col_varchar_key	col_varchar_key	4	test.child1.col_varchar_nokey	2	Using where
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 LEFT JOIN t2 AS grandparent2 USING (col_varchar_nokey)
 WHERE (grandparent1.col_varchar_key) IN
@@ -6594,21 +7262,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #
@@ -7139,9 +7807,9 @@ ON alias2.col_int_nokey = alias1.col_int
 'o' IN (SELECT col_varchar_nokey
 FROM t3);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where; Materialize
+1	PRIMARY	alias1	ALL	NULL	NULL	NULL	NULL	2	Using join buffer (Block Nested Loop)
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t3	ALL	NULL	NULL	NULL	NULL	2	Using where
 SELECT alias1.col_varchar_nokey
 FROM t1 AS alias1
 INNER JOIN v_t2 AS alias2
@@ -7193,10 +7861,10 @@ FROM t1
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1a	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
+1	PRIMARY	t1a	ref	col_int_key	col_int_key	4	const	1	Start temporary
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; End temporary; Using join buffer (Block Nested Loop)
 1	PRIMARY	t1b	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	t2	system	PRIMARY,col_int_key	NULL	NULL	NULL	1	
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where; Materialize
 SELECT t1a.*
 FROM t1 AS t1a
 JOIN t1 AS t1b USING ( col_int_nokey )
@@ -7309,11 +7977,11 @@ ON child1.pk < child2.col_int_nokey
 )
 );
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	grandparent1	ALL	col_int_key	NULL	NULL	NULL	3	Using where
+1	PRIMARY	grandparent1	ALL	col_int_key,col_varchar_key	NULL	NULL	NULL	3	
+1	PRIMARY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize
+1	PRIMARY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; End materialize; Using join buffer (Block Nested Loop)
 1	PRIMARY	grandparent2	index	col_int_key	col_int_key	5	NULL	3	Using where; Using index; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	child1	ALL	NULL	NULL	NULL	NULL	8	Start materialize; Scan
-2	DEPENDENT SUBQUERY	child2	ALL	NULL	NULL	NULL	NULL	1	Using where; End materialize; Using join buffer (Block Nested Loop)
-2	DEPENDENT SUBQUERY	parent1	ALL	col_varchar_key	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
 SELECT grandparent1.col_varchar_nokey
 FROM t1 AS grandparent1 JOIN t1 AS grandparent2 USING (col_int_key)
 WHERE grandparent1.col_varchar_key IN (
@@ -7609,10 +8277,10 @@ FROM t2 LEFT JOIN t3 USING (col_varchar_
 ;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	GP2	system	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where
-2	DEPENDENT SUBQUERY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using index; Start materialize; Scan
-2	DEPENDENT SUBQUERY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index; End materialize
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t2	index	col_varchar_key	col_varchar_key	4	NULL	1	Using where; Using index; Start temporary
+1	PRIMARY	t3	ref	col_varchar_key	col_varchar_key	4	test.t2.col_varchar_key	2	Using index
+1	PRIMARY	GP1	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	Using where; End temporary; Using join buffer (Block Nested Loop)
 SELECT GP1.id
 FROM t1 AS GP1 JOIN t3 AS GP2
 ON GP2.col_varchar_key <> GP1.col_varchar_nokey

=== modified file 'mysql-test/r/subquery_sj_mat_nosj.result'
--- a/mysql-test/r/subquery_sj_mat_nosj.result	2012-02-08 15:25:17 +0000
+++ b/mysql-test/r/subquery_sj_mat_nosj.result	2012-02-13 11:57:09 +0000
@@ -3956,6 +3956,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	3
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	3
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	3
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+3	NULL	NULL
+6	6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+3	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot2.a=ot3.a
+WHERE COALESCE(ot3.a,0) IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 2
+# Example SQ2.1:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# Example SQ2.2:
+explain SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+3	SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	
+2	SUBQUERY	it2	ALL	NULL	NULL	NULL	NULL	4	
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it2)
+AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it2)
+AND ot2.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+6	6	6
+# Test cases, Subquery Pattern 3
+# Example SQ3.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ3.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it2	ALL	NULL	NULL	NULL	NULL	4	
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.3
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+3	SUBQUERY	it2	ALL	NULL	NULL	NULL	NULL	4	
+2	SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# Example SQ3.4
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it2	ALL	NULL	NULL	NULL	NULL	4	
+2	SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND
+(ot1.a, ot2.a) IN (SELECT it1.a, it2.a
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+2	NULL
+3	NULL
+4	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot2.a IN (SELECT a FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a+0 FROM it1)
+AND ot2.a IN (SELECT a+0 FROM it2);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND
+(ot1.a, ot2.a) IN (SELECT it1.a+0, it2.a+0
+FROM it1 JOIN it2 ON it1.a=it2.a);
+a	a
+0	0
+1	NULL
+2	2
+3	NULL
+4	4
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it3)
+LEFT JOIN ot3 ON ot2.a=ot3.a+0 AND ot3.a IN (SELECT a FROM it3);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Test cases, Subquery Pattern 4
+# Example SQ4.1:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# Example SQ4.2:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+# Example SQ4.3:
+explain SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+# Example SQ4.4:
+explain SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	ot3	ALL	NULL	NULL	NULL	NULL	3	Using where; Using join buffer (Block Nested Loop)
+2	SUBQUERY	it1	ALL	NULL	NULL	NULL	NULL	8	
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+# More test cases
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	NULL	NULL
+3	NULL	NULL
+4	NULL	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+2	2	NULL
+4	4	NULL
+6	6	6
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a+0)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a+0 AND ot1.a IN (SELECT a FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a+0 FROM it1);
+a	a	a
+0	0	0
+1	NULL	NULL
+2	2	NULL
+3	NULL	NULL
+4	4	NULL
+5	NULL	NULL
+6	6	6
+7	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1)
+LEFT JOIN
+ot1 AS ot4
+ON ot2.a=ot4.a;
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	2
+3	NULL	NULL	NULL
+4	4	NULL	4
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+SELECT *
+FROM   ot1
+LEFT JOIN
+(ot2 LEFT JOIN ot3 ON ot2.a=ot3.a
+LEFT JOIN ot1 AS ot4 ON ot3.a=ot4.a)
+ON ot1.a=ot2.a AND ot1.a IN (SELECT a FROM it1);
+a	a	a	a
+0	0	0	0
+1	NULL	NULL	NULL
+2	2	NULL	NULL
+3	NULL	NULL	NULL
+4	4	NULL	NULL
+5	NULL	NULL	NULL
+6	6	6	6
+7	NULL	NULL	NULL
+DROP TABLE ot1,ot2,ot3,it1,it2,it3;
+# End of WL#5561
+#
 # Bug#48868: Left outer join in subquery causes segmentation fault in
 #            make_join_select.
 #
@@ -4699,9 +5367,9 @@ SELECT t1.t1field
 FROM t1 LEFT JOIN t1 AS t2 ON t1.t1field IN (SELECT v1field FROM v1);
 t1field
 1
-2
 1
 2
+2
 EXPLAIN
 SELECT t1field
 FROM t1
@@ -6328,12 +6996,12 @@ LEFT JOIN
 ON ot1.a=ot2.a AND ot1.a IN (SELECT a from it1);
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 prepare s from 'SELECT *
 FROM   ot1
@@ -6343,22 +7011,22 @@ ON ot1.a=ot2.a AND ot1.a IN (SELECT a fr
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 execute s;
 a	a	a
 0	0	0
-6	6	6
 1	NULL	NULL
 2	NULL	NULL
 3	NULL	NULL
 4	NULL	NULL
 5	NULL	NULL
+6	6	6
 7	NULL	NULL
 deallocate prepare s;
 DROP TABLE ot1, ot2, ot3, it1;
@@ -6668,21 +7336,21 @@ WHERE parent1.col_varchar_key IN
 FROM t1 AS child1 LEFT JOIN t2 AS child2
 ON (child1.col_varchar_key > child2.col_varchar_nokey)));
 col_varchar_nokey
-i
+a
+e
+h
 h
+i
+i
+p
 q
-a
-v
-u
 s
+u
+v
+w
 y
-z
-h
-p
-e
-i
 y
-w
+z
 DROP TABLE t1, t2;
 # End of test for bug#12603183.
 #

=== modified file 'mysql-test/r/subquery_sj_none.result'
--- a/mysql-test/r/subquery_sj_none.result	2012-01-31 11:19:25 +0000
+++ b/mysql-test/r/subquery_sj_none.result	2012-02-13 11:57:09 +0000
@@ -3898,6 +3898,674 @@ where a1 in (select group_concat(b1) fro
 left(a1,7)	left(a2,7)
 drop table t1_1025, t2_1025, t3_1025;
 #
+# WL#5561: Enable semi join transformation with outer join.
+#
+CREATE TABLE ot1(a INT);
+CREATE TABLE ot2(a INT);
+CREATE TABLE ot3(a INT);
+CREATE TABLE it1(a INT);
+CREATE TABLE it2(a INT);
+CREATE TABLE it3(a INT);
+INSERT INTO ot1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO ot2 VALUES(0),(2),(4),(6);
+INSERT INTO ot3 VALUES(0),(3),(6);
+INSERT INTO it1 VALUES(0),(1),(2),(3),(4),(5),(6),(7);
+INSERT INTO it2 VALUES(0),(2),(4),(6);
+INSERT INTO it3 VALUES(0),(3),(6);
+# Test cases, Subquery Pattern 1
+# Example SQ1.1:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	DEPENDENT SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+# Example SQ1.2:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	Using where; Using join buffer (Block Nested Loop)
+2	DEPENDENT SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+# Example SQ1.3:
+explain SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	ot2	ALL	NULL	NULL	NULL	NULL	4	
+1	PRIMARY	ot1	ALL	NULL	NULL	NULL	NULL	8	Using where; Using join buffer (Block Nested Loop)
+2	DEPENDENT SUBQUERY	it3	ALL	NULL	NULL	NULL	NULL	3	Using where
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+# More test cases
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE ot1.a IN (SELECT a+0 FROM it3);
+a	a
+0	0
+3	NULL
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE COALESCE(ot2.a,0) IN (SELECT a FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+WHERE COALESCE(ot2.a,0) IN (SELECT a+0 FROM it3);
+a	a
+0	0
+1	NULL
+3	NULL
+5	NULL
+6	6
+7	NULL
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a+0
+WHERE (ot1.a,ot2.a) IN (SELECT a, a FROM it3);
+a	a
+0	0
+6	6
+SELECT *
+FROM ot1 LEFT JOIN ot2 ON ot1.a=ot2.a
+LEFT JOIN ot3 ON ot1.a=ot3.a
+WHERE ot1.a IN