List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:January 24 2013 9:51am
Subject:bzr push into mysql-5.6 branch (ole.john.aske:4668 to 4669) Bug#16202425
View as plain text  
 4669 Ole John Aske	2013-01-24
      Fix for bug#16202425 INCORRECT LOGIC USED TO FIND OUTER JOINS IN AQP (ABSTRACT QUERY PLAN)
      
      The AQP module contain the member function ::get_join_type('predecessor')
      which is intended to return whether 'this' table and its 'predecessor'
      table is related with an inner or outer join.
      
      We had implemented this logic by using the nested 'embedding' structures
      in the TABLE_LIST. As MySQL 5.6 seems to have extended the usage of the
      'embedding' to also be used as part of subquery optimization, this code
      is now broken. (And it might even have been broken prior to 5.6...)
      Currently this materializes as crashing RQG tests in our clone
      mysql-5.6-cluster which fails on 
        'DBUG_ASSERT(child_embedding->outer_join != 0);'.
      
      I assume this to be due to 5.6 extending the usage of 'embedding' to not
      only be used as part of inner/outer join nests.
      
      This fix reimplements ::get_join_type() to instead use the
      'first_inner' and 'last_inner' member fields to determine the
      join type between two tables. This seems to also more closely resembles
      how the join types are determined internally in the optimizer.

    modified:
      sql/abstract_query_plan.cc
 4668 Venkata Sidagam	2013-01-24 [merge]
       Bug #11752803  SERVER CRASHES IF MAX_CONNECTIONS DECREASED BELOW 
                      CERTAIN LEVEL
            
      Merging from 5.5 to 5.6

    modified:
      internal/mysql-test/suite/i_main/r/connect.result
      internal/mysql-test/suite/i_main/t/connect.test
      mysys/thr_alarm.c
=== modified file 'sql/abstract_query_plan.cc'

=== modified file 'sql/abstract_query_plan.cc'
--- a/sql/abstract_query_plan.cc	2012-10-30 07:59:01 +0000
+++ b/sql/abstract_query_plan.cc	2013-01-24 09:45:50 +0000
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -73,70 +73,37 @@
     DBUG_ENTER("get_join_type");
     DBUG_ASSERT(get_access_no() > predecessor->get_access_no());
 
-    if (get_join_tab()->table->pos_in_table_list->outer_join != 0)
-    {
-      /*
-        This cover unnested outer joins such as 
-        'select * from t1 left join t2 on t1.attr=t1.pk'.
-       */
+    const JOIN_TAB* const first_inner= get_join_tab()->first_inner;
+    if (first_inner == NULL)
+    {
+      // 'this' is not outer joined with any table.
+      DBUG_PRINT("info", ("JT_INNER_JOIN'ed table %s",
+                           get_join_tab()->table->alias));
+      DBUG_RETURN(JT_INNER_JOIN);
+    }
+
+    /**
+     * Fall Through: 'this' is a member in an outer join,
+     * but 'predecessor' may still be embedded in the same
+     * inner join as 'this'.
+     */
+    const JOIN_TAB* const last_inner= first_inner->last_inner;
+    if (predecessor->get_join_tab() >= first_inner &&
+        predecessor->get_join_tab() <= last_inner)
+    {
+      DBUG_PRINT("info", ("JT_INNER_JOIN between %s and %s",
+                          predecessor->get_join_tab()->table->alias,
+                          get_join_tab()->table->alias));
+      DBUG_RETURN(JT_INNER_JOIN);
+    }
+    else
+    {
       DBUG_PRINT("info", ("JT_OUTER_JOIN between %s and %s",
                           predecessor->get_join_tab()->table->alias,
                           get_join_tab()->table->alias));
       DBUG_RETURN(JT_OUTER_JOIN);
     }
-
-    const TABLE_LIST* const child_embedding= 
-      get_join_tab()->table->pos_in_table_list->embedding;
-
-    if (child_embedding == NULL)
-    {
-      // 'this' is not on the inner side of any left join.
-      DBUG_PRINT("info", ("JT_INNER_JOIN between %s and %s",
-                          predecessor->get_join_tab()->table->alias,
-                          get_join_tab()->table->alias));
-      DBUG_RETURN(JT_INNER_JOIN);
-    }
-
-    DBUG_ASSERT(child_embedding->outer_join != 0);
-
-    const TABLE_LIST *predecessor_embedding= 
-      predecessor->get_join_tab()->table->pos_in_table_list->embedding;
-
-    /*
-      This covers the nested join case, i.e:
-      <table reference> LEFT JOIN (<joined table>).
-      
-      TABLE_LIST objects form a tree where TABLE_LIST::emebedding points to
-      the parent object. Now if child_embedding is non null and not an 
-      ancestor of predecessor_embedding in the embedding tree, then 'this'
-      must be on the inner side of some left join where 'predecessor' is on 
-      the outer side.
-     */
-    while (true)
-    {
-      if (predecessor_embedding == child_embedding)
-      {
-        DBUG_PRINT("info", ("JT_INNER_JOIN between %s and %s",
-                            predecessor->get_join_tab()->table->alias,
-                            get_join_tab()->table->alias));
-        DBUG_RETURN(JT_INNER_JOIN);
-      }
-      else if (predecessor_embedding == NULL)
-      {
-        /*
-           We reached the root of the tree without finding child_embedding,
-           so it must be in another branch and hence on the inner side of some
-           left join where 'predecessor' is on the outer side.
-         */
-        DBUG_PRINT("info", ("JT_OUTER_JOIN between %s and %s",
-                            predecessor->get_join_tab()->table->alias,
-                            get_join_tab()->table->alias));
-        DBUG_RETURN(JT_OUTER_JOIN);
-      }
-      // Iterate through ancestors of predecessor_embedding.
-      predecessor_embedding = predecessor_embedding->embedding;
-    }
-  }
+  } //Table_access::get_join_type
 
   /**
     Get the number of key values for this operation. It is an error

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.6 branch (ole.john.aske:4668 to 4669) Bug#16202425Ole John Aske11 Mar