[Commits] 283b327: Changes for MDEV-12387

shagalla galina.shalygina at mariadb.com
Tue Apr 17 02:06:57 EEST 2018


revision-id: 283b3275742ca22cd1f46a21b1a794f1b52039a9 (mariadb-10.3.4-59-g283b327)
parent(s): 608d6773bff86b82d9fa35e77065cb0b6ed9e547
author: Galina Shalygina
committer: Galina Shalygina
timestamp: 2018-04-17 01:06:57 +0200
message:

Changes for MDEV-12387

Procedures renamed, some missing definitions added.
*Item_direct_view_ref::in_subq_field_transformer_for_having added

---
 sql/item.cc          |   7 ++--
 sql/item.h           |  13 ++++---
 sql/item_cmpfunc.h   |   4 +-
 sql/opt_subselect.cc | 105 ++++++++++++++++++++++++++++++++++++---------------
 sql/sql_derived.cc   |   8 ++--
 sql/sql_select.cc    |   1 +
 6 files changed, 92 insertions(+), 46 deletions(-)

diff --git a/sql/item.cc b/sql/item.cc
index b1134d1..7a6879e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -7904,8 +7904,7 @@ Grouping_tmp_field *find_matching_grouping_field(Item *item,
 }
     
 
-Item *Item_field::derived_grouping_field_transformer_for_where(THD *thd,
-                                                               uchar *arg)
+Item *Item_field::grouping_field_transformer_for_where(THD *thd, uchar *arg)
 {
   st_select_lex *sel= (st_select_lex *)arg;
   Grouping_tmp_field *gr_field= find_matching_grouping_field(this, sel);
@@ -7916,8 +7915,8 @@ Item *Item_field::derived_grouping_field_transformer_for_where(THD *thd,
 
 
 Item *
-Item_direct_view_ref::derived_grouping_field_transformer_for_where(THD *thd,
-                                                                   uchar *arg)
+Item_direct_view_ref::grouping_field_transformer_for_where(THD *thd,
+                                                           uchar *arg)
 {
   if (!item_equal)
     return this;
diff --git a/sql/item.h b/sql/item.h
index 2d8972f..faeb4ae 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1785,8 +1785,7 @@ class Item: public Value_source,
   { return this; }
   virtual Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
   { return this; }
-  virtual Item *derived_grouping_field_transformer_for_where(THD *thd,
-                                                             uchar *arg)
+  virtual Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
   { return this; }
   virtual Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
   { return this; }
@@ -2959,7 +2958,7 @@ class Item_field :public Item_ident
   virtual Item *update_value_transformer(THD *thd, uchar *select_arg);
   Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
   Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
-  Item *derived_grouping_field_transformer_for_where(THD *thd, uchar *arg);
+  Item *grouping_field_transformer_for_where(THD *thd, uchar *arg);
   Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg);
   virtual void print(String *str, enum_query_type query_type);
   bool excl_dep_on_table(table_map tab_map);
@@ -5091,8 +5090,8 @@ class Item_direct_view_ref :public Item_direct_ref
   bool excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred);
   Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
   Item *derived_field_transformer_for_where(THD *thd, uchar *arg);
-  Item *derived_grouping_field_transformer_for_where(THD *thd,
-                                                     uchar *arg);
+  Item *grouping_field_transformer_for_where(THD *thd, uchar *arg);
+  Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg);
 
   void save_val(Field *to)
   {
@@ -5998,7 +5997,9 @@ class Item_cache: public Item_basic_constant,
   { return convert_to_basic_const_item(thd); }
   Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
   { return convert_to_basic_const_item(thd); }
-  Item *derived_grouping_field_transformer_for_where(THD *thd, uchar *arg)
+  Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
+  { return convert_to_basic_const_item(thd); }
+  Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
   { return convert_to_basic_const_item(thd); }
 };
 
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index c2d7a4c..f565f3a 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1260,7 +1260,9 @@ class Item_func_nullif :public Item_func_case_expression
   { reset_first_arg_if_needed(); return this; }
   Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
   { reset_first_arg_if_needed(); return this; }
-  Item *derived_grouping_field_transformer_for_where(THD *thd, uchar *arg)
+  Item *grouping_field_transformer_for_where(THD *thd, uchar *arg)
+  { reset_first_arg_if_needed(); return this; }
+  Item *in_subq_field_transformer_for_having(THD *thd, uchar *arg)
   { reset_first_arg_if_needed(); return this; }
 };
 
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 8f6483e..eac779c 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5898,7 +5898,6 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
   List_iterator<TABLE_LIST> li(*join_list);
   THD *thd= join->thd;
   DBUG_ENTER("setup_jtbm_semi_joins");
-  eq_list.empty();
 
   while ((table= li++))
   {
@@ -6432,14 +6431,39 @@ bool Item_equal::excl_dep_on_in_subq_left_part(Item_in_subselect *subq_pred)
 }
 
 
-Item *Item_field::in_subq_field_transformer_for_having(THD *thd, uchar *arg)
+/**
+  @brief
+    Transforms item so it can be pushed into the IN subquery HAVING clause
+
+  @param thd        the thread handle
+  @param in_item    the item for which pushable item should be created
+  @param subq_pred  the IN subquery predicate
+
+  @details
+    This method traverses the fields of the select of the IN subquery predicate
+    subq_pred trying to find the corresponding item 'new_item' for in_item.
+    If in_item has equal items it traverses the fields of the select of
+    subq_pred for each equal item trying to find corresponding item 'new_item'.
+    If 'new_item' is found, a shell for this item is created. This shell can be
+    pushed into the HAVING part of subq_pred select.
+
+  @retval <item*>  reference to the created corresonding item shell for in_item
+  @retval NULL     if mistake occurs
+*/
+
+static
+Item *get_corresponding_item_for_in_subq_having(THD *thd, Item *in_item,
+                                                Item_in_subselect *subq_pred)
 {
-  Item_in_subselect *subq_pred= (Item_in_subselect *)arg;
+  DBUG_ASSERT(in_item->type() == Item::FIELD_ITEM ||
+              (in_item->type() == Item::REF_ITEM &&
+              ((Item_ref *) in_item)->ref_type() == Item_ref::VIEW_REF));
 
-  List_iterator<In_subq_field> li(subq_pred->comparable_fields);
   In_subq_field *fi;
-  Item_field *field_item= (Item_field *) (real_item());
   Item *new_item;
+  List_iterator<In_subq_field> li(subq_pred->comparable_fields);
+  Item_field *field_item= (Item_field *) (in_item->real_item());
+  Item_equal *item_equal= in_item->get_item_equal();
 
   if (item_equal)
   {
@@ -6452,10 +6476,11 @@ Item *Item_field::in_subq_field_transformer_for_having(THD *thd, uchar *arg)
       while ((fi= li++))
       {
         if (field_item->field ==
-	    ((Item_field *) (fi->left_it->real_item()))->field)
-	{
-	  new_item= fi->right_it;
-	}
+            ((Item_field *) (fi->left_it->real_item()))->field)
+        {
+          new_item= fi->right_it;
+          break;
+        }
       }
     }
   }
@@ -6465,39 +6490,56 @@ Item *Item_field::in_subq_field_transformer_for_having(THD *thd, uchar *arg)
     while ((fi= li++))
     {
       if (field_item->field ==
-	  ((Item_field *) (fi->left_it->real_item()))->field)
+        ((Item_field *) (fi->left_it->real_item()))->field)
+      {
         new_item= fi->right_it;
+        break;
+      }
     }
   }
 
-  if (!new_item)
-    return this;
-
-  Item_ref *ref=
-    new (thd->mem_root) Item_ref(thd,
-				 &subq_pred->unit->first_select()->context,
-                                 NullS, NullS,
-                                 &new_item->name);
+  if (new_item)
+  {
+    Item_ref *ref=
+      new (thd->mem_root) Item_ref(thd,
+                                   &subq_pred->unit->first_select()->context,
+                                   NullS, NullS,
+                                   &new_item->name);
     return ref;
-
+  }
   DBUG_ASSERT(0);
   return NULL;
 }
 
 
+Item *Item_field::in_subq_field_transformer_for_having(THD *thd, uchar *arg)
+{
+  return get_corresponding_item_for_in_subq_having(thd, this,
+                                                   (Item_in_subselect *)arg);
+}
+
+
+Item *Item_direct_view_ref::in_subq_field_transformer_for_having(THD *thd,
+                                                                 uchar *arg)
+{
+  return get_corresponding_item_for_in_subq_having(thd, this,
+                                                   (Item_in_subselect *)arg);
+}
+
+
 /**
   @brief
     Find fields that are used in the GROUP BY of the select
 
   @param thd     the thread handle
-  @param sel     select of the right part of IN subquery
-  @param fields  fields list of the left part of IN subquery
+  @param sel     the select of the IN subquery predicate select
+  @param fields  fields of the left part of the IN subquery predicate
 
   @details
-    This method looks through the fields which are used in the GROUP BY of
-    sel and saves this fields with their prototypes from the fields list
-    of the left part of IN subquery
+    This method traverses fields which are used in the GROUP BY of
+    sel and saves them with their corresponding items from fields.
 */
+
 void grouping_fields_in_the_in_subq_left_part(THD *thd,
                                               st_select_lex *sel,
                                               List<In_subq_field> *fields,
@@ -6568,6 +6610,7 @@ void grouping_fields_in_the_in_subq_left_part(THD *thd,
   @retval TRUE   if an error occurs
   @retval FALSE  otherwise
 */
+
 bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
 {
   DBUG_ENTER("Item_in_subselect::pushdown_cond_for_in_subquery");
@@ -6640,12 +6683,12 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
 
     if (cond_over_partition_fields)
       cond_over_partition_fields= cond_over_partition_fields->transform(thd,
-           &Item::derived_grouping_field_transformer_for_where, (uchar*) sel);
+        &Item::grouping_field_transformer_for_where, (uchar*) sel);
 
     if (cond_over_partition_fields)
     {
       cond_over_partition_fields->walk(
-	  &Item::cleanup_excluding_const_fields_processor, 0, 0);
+	      &Item::cleanup_excluding_const_fields_processor, 0, 0);
       sel->cond_pushed_into_where= cond_over_partition_fields;
     }
     goto exit;
@@ -6667,9 +6710,10 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
     into the sel of the WHERE clause.
   */
   if (cond_over_grouping_fields)
-      cond_over_grouping_fields= cond_over_grouping_fields->transform(thd,
-                           &Item::derived_grouping_field_transformer_for_where,
-                           (uchar*) sel);
+      cond_over_grouping_fields=
+        cond_over_grouping_fields->transform(thd,
+                                   &Item::grouping_field_transformer_for_where,
+                                   (uchar*) sel);
 
   if (cond_over_grouping_fields)
   {
@@ -6695,8 +6739,7 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
   if (!extracted_cond)
     goto exit;
 
-  extracted_cond->walk(&Item::cleanup_excluding_const_fields_processor,
-                              0, 0);
+  extracted_cond->walk(&Item::cleanup_excluding_const_fields_processor, 0, 0);
   sel->cond_pushed_into_having= extracted_cond;
 
 exit:
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index f2179ae..1c62a38 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1310,8 +1310,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
         sl->build_cond_for_grouping_fields(thd, extracted_cond_copy, true);
       if (cond_over_partition_fields)
         cond_over_partition_fields= cond_over_partition_fields->transform(thd,
-                         &Item::derived_grouping_field_transformer_for_where,
-                         (uchar*) sl);
+                                  &Item::grouping_field_transformer_for_where,
+                                  (uchar*) sl);
       if (cond_over_partition_fields)
       {
         cond_over_partition_fields->walk(
@@ -1364,8 +1364,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
     */
     if (cond_over_grouping_fields)
       cond_over_grouping_fields= cond_over_grouping_fields->transform(thd,
-                         &Item::derived_grouping_field_transformer_for_where,
-                         (uchar*) sl);
+                              &Item::grouping_field_transformer_for_where,
+                              (uchar*) sl);
      
     if (cond_over_grouping_fields)
     {
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 5a342c8..e7bc68e 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1750,6 +1750,7 @@ JOIN::optimize_inner()
         conds->fix_fields(thd, &conds)))
       DBUG_RETURN(TRUE);
   }
+  eq_list.empty();
 
   if (select_lex->cond_pushed_into_where)
   {


More information about the commits mailing list