List:Commits« Previous MessageNext Message »
From:Jorgen Loland Date:September 2 2010 2:20pm
Subject:bzr push into mysql-next-mr-bugfixing branch (jorgen.loland:3234 to 3235)
View as plain text  
 3235 Jorgen Loland	2010-09-02
      Cast return of log10(double) to int to avoid warning

    modified:
      sql/sql_select.cc
 3234 Jorgen Loland	2010-09-02
      Bug#49129 - Wrong result with IN-subquery with join_cache_level=6 
                  and firstmatch=off
      
      Patch based on contribution from Sergey Petrunia.
      
      Consider the query:
      
      SELECT * FROM t0 WHERE t0.a IN (
         SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
      
      With join cache level 6, this query only returns the first tuple
      from t0 that has a match in the subquery. Consider the relevant part
      of EXPLAIN:
      
      t0    | Using where                                   |
      t1    | Start temporary; Using join buffer            |
      t2    | Using where; End temporary; Using join buffer |
      
      When the optimizer decides to use join buffers, temporary tables
      created for duplicate weedout should extend to the first table
      after const tables. I.e., Start temporary should be printed for
      t0 above.
      
      The reason for the bug is that setup_semijoin_dups_elimination()
      is called before the final decision is made in
      check_join_cache_usage() on whether or not to use join buffering.
      In this case, use_join_buffer==false for t1 and t2 during
      setup_semijoin_dups_elimination(), and the range of tables to
      buffer is therefore not extended to t0.
      
      Since check_join_cache_usage() needs to know if duplicate weedout
      is used, so moving setup_semijoin_dups_elimination() from before
      check_join_cache_usage() to after it is not possible. 
      
      The temporary fix of this patch is to use a rough estimate of
      whether join buffering will be used in
      setup_semijoin_dups_elimination(). This rough test covers more 
      cases than actually end up with join buffering, and in these cases 
      we now extend the temporary table to store rowids for more tables 
      than strictly required, i.e., the first non-const table up to the 
      start of the semijoin. A proper (but much more costly to do) fix 
      would be to merge the loops of setup_semijoin_dups_elimination() 
      and make_join_readinfo() (which calls check_join_cache_usage()).
     @ mysql-test/r/subquery_sj_all.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_all_jcl6.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_all_jcl7.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_dupsweed.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_dupsweed_jcl6.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_dupsweed_jcl7.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_firstmatch.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_firstmatch_jcl6.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_firstmatch_jcl7.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_loosescan.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_loosescan_jcl6.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_loosescan_jcl7.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_mat.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_mat_jcl6.result
        Recorded new explain output for queries using duplicate weedout.
     @ mysql-test/r/subquery_sj_mat_jcl7.result
        Recorded new explain output for queries using duplicate weedout.
     @ sql/sql_select.cc
        setup_semijoin_dups_elimination() relied on
        best_position[i].use_join_buffer when checking whether temporary
        tables for duplicate weedout should be extended to the first
        table of the execution plan. However, use_join_buffer is not
        reliable at this stage, so setup_semijoin_dups_elimination()
        needs to use a rough estimate instead.
     @ sql/sql_select.h
        Made st_join_table::use_quick an enum
     @ sql/sql_test.cc
        Made st_join_table::use_quick an enum

    modified:
      mysql-test/r/subquery_sj_all.result
      mysql-test/r/subquery_sj_all_jcl6.result
      mysql-test/r/subquery_sj_all_jcl7.result
      mysql-test/r/subquery_sj_dupsweed.result
      mysql-test/r/subquery_sj_dupsweed_jcl6.result
      mysql-test/r/subquery_sj_dupsweed_jcl7.result
      mysql-test/r/subquery_sj_firstmatch.result
      mysql-test/r/subquery_sj_firstmatch_jcl6.result
      mysql-test/r/subquery_sj_firstmatch_jcl7.result
      mysql-test/r/subquery_sj_loosescan.result
      mysql-test/r/subquery_sj_loosescan_jcl6.result
      mysql-test/r/subquery_sj_loosescan_jcl7.result
      mysql-test/r/subquery_sj_mat.result
      mysql-test/r/subquery_sj_mat_jcl6.result
      mysql-test/r/subquery_sj_mat_jcl7.result
      sql/sql_join_cache.cc
      sql/sql_select.cc
      sql/sql_select.h
      sql/sql_test.cc
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-09-02 07:34:10 +0000
+++ b/sql/sql_select.cc	2010-09-02 14:20:05 +0000
@@ -22167,7 +22167,7 @@ void select_describe(JOIN *join, bool ne
     {
       SELECT_LEX *last_select= join->unit->first_select()->last_select();
       // # characters needed to print select_number of last select
-      int last_length= log10((double)last_select->select_number)+1;
+      int last_length= (int)log10((double)last_select->select_number)+1;
 
       SELECT_LEX *sl= join->unit->first_select();
       uint len= 6, lastop= 0;


Attachment: [text/bzr-bundle] bzr/jorgen.loland@oracle.com-20100902142005-fgs50vx5edrv7eu2.bundle
Thread
bzr push into mysql-next-mr-bugfixing branch (jorgen.loland:3234 to 3235) Jorgen Loland2 Sep