[Commits] 3630a00e258273ada7f783a514600aafcd3f13f9 Fixed bug mdev-10782. This bug in the code of Item_ref::build_clone could cause corruption of items in where conditions. Also made sure that equality predicates extracted from multiple equality items to be pushed into materialized views were cloned.

Igor Babaev igor at askmonty.org
Mon Sep 12 10:07:02 EEST 2016


commit 3630a00e258273ada7f783a514600aafcd3f13f9
Author: Igor Babaev <igor at askmonty.org>
Commit: Igor Babaev <igor at askmonty.org>

    Fixed bug mdev-10782.
    This bug in the code of Item_ref::build_clone could
    cause corruption of items in where conditions.
    Also made sure that equality predicates extracted
    from multiple equality items to be pushed into
    materialized views were cloned.
---
 mysql-test/r/derived_cond_pushdown.result |   25 +++++++++++++++++++++++++
 mysql-test/t/derived_cond_pushdown.test   |   24 +++++++++++++++++++++++-
 sql/item.cc                               |   10 ++++++++++
 sql/table.cc                              |   13 ++++++++++---
 4 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index 069041c..3b7eb58 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -6982,3 +6982,28 @@ drop view v1,v2,v3,v4;
 drop view v_union,v2_union,v3_union,v4_union;
 drop view v_double,v_char,v_decimal;
 drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
+#
+# MDEV-10782: condition extracted from a multiple equality
+#             pushed into HAVING
+#
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN EXTENDED
+SELECT *
+FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
+WHERE f = 8;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	PRIMARY	<derived3>	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
+3	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	2	100.00	
+Warnings:
+Note	1003	select `sq1`.`f` AS `f` from (select min(`test`.`t1`.`i`) AS `f` from `test`.`t1` having (`f` = 8)) `sq1` where (`sq1`.`f` = 8)
+SELECT *
+FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
+WHERE f = 8;
+f
+SELECT *
+FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
+WHERE f = 1;
+f
+1
+DROP TABLE t1;
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index 41342db..7a85c53 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -877,4 +877,26 @@ eval explain format=json $query;
 drop view v1,v2,v3,v4;
 drop view v_union,v2_union,v3_union,v4_union;
 drop view v_double,v_char,v_decimal;
-drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;    
\ No newline at end of file
+drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;  
+
+--echo #
+--echo # MDEV-10782: condition extracted from a multiple equality
+--echo #             pushed into HAVING
+--echo #
+
+CREATE TABLE t1 (i int);
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN EXTENDED
+SELECT *
+  FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
+    WHERE f = 8;
+SELECT *
+  FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
+    WHERE f = 8;
+SELECT *
+  FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
+    WHERE f = 1;
+DROP TABLE t1;
+
+
+  
\ No newline at end of file
diff --git a/sql/item.cc b/sql/item.cc
index 3070dc8..d461386 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2296,10 +2296,16 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
   if (!copy)
     return 0;
   if (arg_count > 2)
+  {
     copy->args= 
       (Item**) alloc_root(mem_root, sizeof(Item*) * arg_count);
+    if (!copy->args)
+      return 0;
+  }
   else if (arg_count > 0)
     copy->args= copy->tmp_arg;
+
+   
   for (uint i= 0; i < arg_count; i++)
   {
     Item *arg_clone= args[i]->build_clone(thd, mem_root);
@@ -2332,6 +2338,10 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
   Item_ref *copy= (Item_ref *) get_copy(thd, mem_root);
   if (!copy)
     return 0;
+  copy->ref= 
+      (Item**) alloc_root(mem_root, sizeof(Item*));
+  if (!copy->ref)
+      return 0;
   Item *item_clone= (* ref)->build_clone(thd, mem_root);
   if (!item_clone)
     return 0;
diff --git a/sql/table.cc b/sql/table.cc
index a8a47e7..9a9dee6 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8057,8 +8057,12 @@ void TABLE_LIST::check_pushable_cond_for_table(Item *cond)
     {
       if (!(item->used_tables() == tab_map))
 	continue;
-      Item_func_eq *eq= 
-	new (thd->mem_root) Item_func_eq(thd, item, left_item);
+      Item_func_eq *eq= 0;
+      Item *left_item_clone= left_item->build_clone(thd, thd->mem_root);
+      Item *right_item_clone= item->build_clone(thd, thd->mem_root);
+      if (left_item_clone && right_item_clone)
+	eq= new (thd->mem_root) Item_func_eq(thd, right_item_clone,
+                                         left_item_clone);
       if (eq)
       {
 	i++;
@@ -8071,10 +8075,13 @@ void TABLE_LIST::check_pushable_cond_for_table(Item *cond)
 	  new_cond= new (thd->mem_root) Item_cond_and(thd, new_cond, eq);
 	  break;
 	default:
-	  ((Item_cond_and*)new_cond)->argument_list()->push_back(eq, thd->mem_root);
+	  ((Item_cond_and*)new_cond)->argument_list()->push_back(eq,
+                                                                 thd->mem_root);
 	}
       }
     }
+    if (new_cond)
+      new_cond->fix_fields(thd, &new_cond);
     return new_cond;
   }
   else if (cond->get_extraction_flag() != NO_EXTRACTION_FL)


More information about the commits mailing list