[Commits] a9bcdbf: MDEV-8989: ORDER BY optimizer ignores equality propagation

Sergei Petrunia psergey at askmonty.org
Mon May 23 21:11:32 EEST 2016


revision-id: a9bcdbfeb80337fed8ba081805a7f0101b19c94f
parent(s): 29a0a333557c47e03a93577aae009c7c6ee91e67
committer: Sergei Petrunia
branch nick: 10.1-dbg4
timestamp: 2016-05-23 21:11:32 +0300
message:

MDEV-8989: ORDER BY optimizer ignores equality propagation

Post-review fixes for Variant#3 of the fix.
Correctly handle Item_direct_ref objects:

- Use item->propagate_equal_fields
- Use item->get_item_equal().

---
 sql/sql_select.cc |   37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index aea46aa..c8a02a5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -12337,28 +12337,35 @@ static void update_depend_map_for_order(JOIN *join, ORDER *order)
               order->item[0]->real_item()->type() == Item::FIELD_ITEM &&
               join->cond_equal)
           {
-            Item_field *item_field= (Item_field*)(order->item[0]->real_item());
-            List_iterator<Item_equal> li(join->cond_equal->current_level);
-            Item_equal *item_eq;
             table_map first_table_bit=
               join->join_tab[join->const_tables].table->map;
-            table_map needed_tbl_map= item_field->used_tables() |
-                                      first_table_bit;
-            while ((item_eq= li++))
+
+            Item *item= order->item[0];
+
+            /* 
+              We are using Context_identity below. This means only do
+              substitution when equality means
+            */
+            Item *res= item->propagate_equal_fields(join->thd,
+                                                    Value_source::
+                                                    Context_identity(),
+                                                    join->cond_equal);
+            if (res != item)
+            {
+              /* Substituted to a constant */
+              can_subst_to_first_table= true;
+            }
+            else
             {
-              if ((item_eq->used_tables() & needed_tbl_map) &&
-                  item_eq->contains(item_field->field))
+              Item_equal *item_eq= item->get_item_equal();
+              if (item_eq)
               {
-                /* The field is from this Item_equal: */
-                item_field->item_equal= item_eq;
-
                 Item *first= item_eq->get_first(NO_PARTICULAR_TAB, NULL);
                 if (first->const_item() || first->used_tables() ==
                                            first_table_bit)
                 {
                   can_subst_to_first_table= true;
                 }
-                break;
               }
             }
           }
@@ -21865,13 +21872,13 @@ SORT_FIELD *make_unireg_sortorder(THD *thd, JOIN *join,
     table_map item_map= first->used_tables();
     if (join && (item_map & ~join->const_table_map) &&
         !(item_map & first_table_bit) && join->cond_equal &&
-        (first->real_item()->type() == Item::FIELD_ITEM))
+         first->get_item_equal())
     {
-      /* 
+      /*
         Ok, this is the case descibed just above. Get the first element of the
         multi-equality.
       */
-      Item_equal *item_eq= ((Item_field*)first->real_item())->item_equal;
+      Item_equal *item_eq= first->get_item_equal();
       first= item_eq->get_first(NO_PARTICULAR_TAB, NULL);
     }
 


More information about the commits mailing list