MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Tor Didriksen Date:June 14 2010 12:38pm
Subject:bzr commit into mysql-next-mr-opt-backporting branch (tor.didriksen:3197)
Bug#52538
View as plain text  
#At file:///export/home/didrik/repo/next-mr-opt-backporting-bug52538-calloc/ based on revid:jorgen.loland@stripped

 3197 Tor Didriksen	2010-06-14
      Bug #52538 Valgrind bug: Item_in_subselect::init_left_expr_cache()
      
      The JOIN_TAB created in make_simple_join() was not properly initialized.
      Use thd->calloc() rather than thd->alloc()
     @ mysql-test/r/subselect_mat.result
        Add test case.
     @ mysql-test/t/subselect_mat.test
        Add test case.
     @ sql/item_subselect.cc
        Do not ignore return value of init_left_expr_cache()
        Initialize allocated JOIN_TAB.
        Don't do function calls in DBUG_RETURN().
     @ sql/item_subselect.h
        Introduce new member need_expr_cache.
     @ sql/sql_select.cc
        Initialize allocated JOIN_TAB.

    modified:
      mysql-test/r/subselect_mat.result
      mysql-test/t/subselect_mat.test
      sql/item_subselect.cc
      sql/item_subselect.h
      sql/sql_select.cc
=== modified file 'mysql-test/r/subselect_mat.result'
--- a/mysql-test/r/subselect_mat.result	2010-06-09 14:16:33 +0000
+++ b/mysql-test/r/subselect_mat.result	2010-06-14 12:38:20 +0000
@@ -1224,3 +1224,53 @@ SELECT pk FROM t1 WHERE (b,c,d) IN (SELE
 pk
 2
 DROP TABLE t1, t2;
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER,
+col_int_key INTEGER,
+col_varchar_key VARCHAR(1),
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_varchar_key, col_int_key)
+)
+;
+INSERT INTO t1 (
+col_int_key, col_int_nokey, col_varchar_key
+) 
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+SELECT table2.col_varchar_key AS field1,
+table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+ON (table2.col_varchar_key = table1.col_varchar_key  ) ) 
+WHERE table1.pk = 6
+HAVING  ( field2 ) IN 
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2 
+FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2 
+;
+field1	field2
+t	1
+t	2
+drop table t1;

=== modified file 'mysql-test/t/subselect_mat.test'
--- a/mysql-test/t/subselect_mat.test	2010-04-06 13:54:40 +0000
+++ b/mysql-test/t/subselect_mat.test	2010-06-14 12:38:20 +0000
@@ -897,3 +897,58 @@ SELECT pk FROM t1 WHERE (a) IN (SELECT a
 SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
 DROP TABLE t1, t2;
 
+#
+# Bug #52538 Valgrind bug: Item_in_subselect::init_left_expr_cache()
+#
+CREATE TABLE t1 (
+  pk INTEGER AUTO_INCREMENT,
+  col_int_nokey INTEGER,
+  col_int_key INTEGER,
+
+  col_varchar_key VARCHAR(1),
+
+  PRIMARY KEY (pk),
+  KEY (col_int_key),
+  KEY (col_varchar_key, col_int_key)
+)
+;
+
+INSERT INTO t1 (
+  col_int_key, col_int_nokey, col_varchar_key
+) 
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+
+SELECT table2.col_varchar_key AS field1,
+       table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+       ON (table2.col_varchar_key = table1.col_varchar_key  ) ) 
+WHERE table1.pk = 6
+HAVING  ( field2 ) IN 
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2 
+  FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+         ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2 
+;
+
+drop table t1;

=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc	2010-05-14 10:58:39 +0000
+++ b/sql/item_subselect.cc	2010-06-14 12:38:20 +0000
@@ -150,6 +150,7 @@ void Item_in_subselect::cleanup()
     left_expr_cache= NULL;
   }
   first_execution= TRUE;
+  need_expr_cache= TRUE;
   Item_subselect::cleanup();
   DBUG_VOID_RETURN;
 }
@@ -325,8 +326,9 @@ bool Item_in_subselect::exec()
     - on a cost-based basis, that takes into account the cost of a cache
       lookup, the cache hit rate, and the savings per cache hit.
   */
-  if (!left_expr_cache && exec_method == MATERIALIZATION)
-    init_left_expr_cache();
+  if (need_expr_cache && !left_expr_cache && exec_method == MATERIALIZATION &&
+      init_left_expr_cache())
+    DBUG_RETURN(TRUE);
 
   /* If the new left operand is already in the cache, reuse the old result. */
   if (left_expr_cache && test_if_item_cache_changed(*left_expr_cache) < 0)
@@ -342,7 +344,8 @@ bool Item_in_subselect::exec()
     we don't call it, the next call to item::val_int() will return whatever
     result was computed by its previous call.
   */
-  DBUG_RETURN(Item_subselect::exec());
+  const bool retval= Item_subselect::exec();
+  DBUG_RETURN(retval);
 }
 
 
@@ -743,6 +746,7 @@ bool Item_in_subselect::test_limit(st_se
 Item_in_subselect::Item_in_subselect(Item * left_exp,
 				     st_select_lex *select_lex):
   Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
+  need_expr_cache(TRUE),
   optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
   upper_item(0)
 {
@@ -1911,8 +1915,7 @@ bool Item_in_subselect::setup_engine()
   but it takes a different kind of collection of items, and the
   list we push to is dynamically allocated.
 
-  @retval TRUE  if a memory allocation error occurred or the cache is
-                not applicable to the current query
+  @retval TRUE  if a memory allocation error occurred
   @retval FALSE if success
 */
 
@@ -1928,7 +1931,11 @@ bool Item_in_subselect::init_left_expr_c
     been optimzied away.
   */ 
   if (!outer_join || !outer_join->tables || !outer_join->tables_list)
-    return TRUE;
+  {
+    need_expr_cache= FALSE;
+    return FALSE;
+  }
+
   /*
     If we use end_[send | write]_group to handle complete rows of the outer
     query, make the cache of the left IN operand use Item_field::result_field
@@ -3146,7 +3153,7 @@ bool subselect_hash_sj_engine::init_perm
     - here we initialize only those members that are used by
       subselect_uniquesubquery_engine, so these objects are incomplete.
   */ 
-  if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
+  if (!(tab= (JOIN_TAB*) thd->calloc(sizeof(JOIN_TAB))))
     DBUG_RETURN(TRUE);
   tab->table= tmp_table;
   tab->ref.key= 0; /* The only temp table index. */

=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h	2010-06-14 06:59:59 +0000
+++ b/sql/item_subselect.h	2010-06-14 12:38:20 +0000
@@ -296,6 +296,8 @@ protected:
   */
   List<Cached_item> *left_expr_cache;
   bool first_execution;
+  /* The need for expr cache may be optimized away, see init_left_expr_cache() */
+  bool need_expr_cache;
 
   /*
     expr & optimizer used in subselect rewriting to store Item for
@@ -365,6 +367,7 @@ public:
   Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
   Item_in_subselect()
     :Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
+    need_expr_cache(TRUE),
     optimizer(0), abort_on_null(0), pushed_cond_guards(NULL),
     exec_method(NOT_TRANSFORMED), upper_item(0)
   {}

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-06-14 06:53:02 +0000
+++ b/sql/sql_select.cc	2010-06-14 12:38:20 +0000
@@ -8337,7 +8337,7 @@ static bool get_best_combination(JOIN *j
 
   table_count=join->tables;
   if (!(join->join_tab=join_tab=
-	(JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
+	(JOIN_TAB*) thd->calloc(sizeof(JOIN_TAB)*table_count)))
     DBUG_RETURN(TRUE);
 
   join->full_join=0;
@@ -8636,7 +8636,7 @@ JOIN::make_simple_join(JOIN *parent, TAB
     to this function through JOIN::exec (may happen for sub-queries).
   */
   if (!parent->join_tab_reexec &&
-      !(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
+      !(parent->join_tab_reexec= (JOIN_TAB*) thd->calloc(sizeof(JOIN_TAB))))
     DBUG_RETURN(TRUE);                        /* purecov: inspected */
 
   join_tab= parent->join_tab_reexec;
@@ -16246,9 +16246,15 @@ Next_select_func setup_end_select_func(J
     if ((join->sort_and_group ||
          (join->procedure && join->procedure->flags & PROC_GROUP)) &&
         !tmp_tbl->precomputed_group_by)
+    {
+      DBUG_PRINT("info",("Using end_send_group"));
       end_select= end_send_group;
+    }
     else
+    {
+      DBUG_PRINT("info",("Using end_send"));
       end_select= end_send;
+    }
   }
   return end_select;
 }


Attachment: [text/bzr-bundle] bzr/tor.didriksen@sun.com-20100614123820-1uglhg2bu9kned83.bundle
Thread
bzr commit into mysql-next-mr-opt-backporting branch (tor.didriksen:3197)Bug#52538Tor Didriksen14 Jun