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/ 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 new (thd->mem_root) 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_bitmap.h
        Initialize Bitmap in constructor.
     @ sql/sql_select.cc
        Initialize allocated JOIN_TAB.
        Remove some assignments, no longer necessary since object is properly constructed.
     @ sql/sql_select.h
        Let st_join_table inherit new allocators from Sql_alloc.
        Implement conctructor for st_join_table

    modified:
      mysql-test/r/subselect_mat.result
      mysql-test/t/subselect_mat.test
      sql/item_subselect.cc
      sql/item_subselect.h
      sql/sql_bitmap.h
      sql/sql_select.cc
      sql/sql_select.h
=== 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:37:58 +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:37:58 +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:37:58 +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= new (thd->mem_root) 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:37:58 +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_bitmap.h'
--- a/sql/sql_bitmap.h	2010-05-14 10:58:39 +0000
+++ b/sql/sql_bitmap.h	2010-06-14 12:37:58 +0000
@@ -100,7 +100,7 @@ template <> class Bitmap<64>
 {
   ulonglong map;
 public:
-  Bitmap<64>() { }
+  Bitmap<64>() : map(0) { }
 #if defined(__NETWARE__) || defined(__MWERKS__)
   /*
     Metwork compiler gives error on Bitmap<64>

=== 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:37:58 +0000
@@ -4223,7 +4223,7 @@ make_join_statistics(JOIN *join, TABLE_L
   DBUG_ENTER("make_join_statistics");
 
   table_count=join->tables;
-  stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
+  stat= new (join->thd->mem_root) JOIN_TAB[table_count];
   stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
   table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
   if (!stat || !stat_ref || !table_vector)
@@ -4240,10 +4240,6 @@ make_join_statistics(JOIN *join, TABLE_L
        s++, tables= tables->next_leaf, i++)
   {
     stat_vector[i]=s;
-    s->keys.init();
-    s->const_keys.init();
-    s->checked_keys.init();
-    s->needed_reg.init();
     table_vector[i]=s->table=table=tables->table;
     table->pos_in_table_list= tables;
     error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
@@ -4258,10 +4254,8 @@ make_join_statistics(JOIN *join, TABLE_L
     bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys);
     all_table_map|= table->map;
     s->join=join;
-    s->info=0;					// For describe
 
     s->dependent= tables->dep_tables;
-    s->key_dependent= 0;
     if (tables->schema_table)
       table->file->stats.records= 2;
     table->quick_condition_rows= table->file->stats.records;
@@ -8336,8 +8330,7 @@ static bool get_best_combination(JOIN *j
   DBUG_ENTER("get_best_combination");
 
   table_count=join->tables;
-  if (!(join->join_tab=join_tab=
-	(JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
+  if (!(join->join_tab= join_tab= new (thd->mem_root) JOIN_TAB[table_count]))
     DBUG_RETURN(TRUE);
 
   join->full_join=0;
@@ -8636,8 +8629,8 @@ 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))))
-    DBUG_RETURN(TRUE);                        /* purecov: inspected */
+      !(parent->join_tab_reexec= new (thd->mem_root) JOIN_TAB))
+    DBUG_RETURN(TRUE);                      /* purecov: inspected */
 
   join_tab= parent->join_tab_reexec;
   parent->table_reexec[0]= temp_table;
@@ -16246,9 +16239,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;
 }

=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h	2010-06-11 12:27:38 +0000
+++ b/sql/sql_select.h	2010-06-14 12:37:58 +0000
@@ -179,9 +179,10 @@ inline bool sj_is_materialize_strategy(u
   return strategy >= SJ_OPT_MATERIALIZE_LOOKUP;
 }
 
-typedef struct st_join_table
+typedef struct st_join_table : public Sql_alloc
 {
-  st_join_table() {}                          /* Remove gcc warning */
+  st_join_table();
+
   TABLE		*table;
   KEYUSE	*keyuse;			/**< pointer to first used key */
   SQL_SELECT	*select;
@@ -380,6 +381,91 @@ typedef struct st_join_table
   uint get_sj_strategy() const;
 } JOIN_TAB;
 
+
+inline
+st_join_table::st_join_table()
+  : table(NULL),
+    keyuse(NULL),
+    select(NULL),
+    select_cond(NULL),
+    quick(NULL),
+    on_expr_ref(NULL),
+    cond_equal(NULL),
+    first_inner(NULL),
+    found(FALSE),
+    not_null_compl(FALSE),
+    last_inner(NULL),
+    first_upper(NULL),
+    first_unmatched(NULL),
+    pre_idx_push_select_cond(NULL),
+    info(NULL),
+    packed_info(0),
+    read_first_record(NULL),
+    next_select(NULL),
+    read_record(),
+    save_read_first_record(NULL),
+    save_read_record(NULL),
+    worst_seeks(0.0),
+    const_keys(),
+    checked_keys(),
+    needed_reg(),
+    keys(),
+
+    records(0),
+    found_records(0),
+    read_time(0),
+
+    dependent(0),
+    key_dependent(0),
+    use_quick(0),
+    index(0),
+    status(0),
+    used_fields(0),
+    used_fieldlength(0),
+    used_blobs(0),
+    used_null_fields(0),
+    used_rowid_fields(0),
+    used_uneven_bit_fields(0),
+    type(JT_UNKNOWN),
+    cached_eq_ref_table(FALSE),
+    eq_ref_table(FALSE),
+    not_used_in_distinct(FALSE),
+    sorted(FALSE),
+
+    limit(0),
+    ref(),
+    use_join_cache(FALSE),
+    cache(NULL),
+
+    cache_idx_cond(NULL),
+    cache_select(NULL),
+    join(NULL),
+
+    emb_sj_nest(NULL),
+    first_sj_inner_tab(NULL),
+    last_sj_inner_tab(NULL),
+
+    flush_weedout_table(NULL),
+    check_weed_out_table(NULL),
+    do_firstmatch(NULL),
+    loosescan_match_tab(NULL),
+    loosescan_buf(NULL),
+    loosescan_key_len(0),
+    found_match(FALSE),
+
+    keep_current_rowid(0),
+    embedding_map(0)
+{
+  /*
+    @todo Add constructor to READ_RECORD.
+    All users do init_read_record(), which does bzero(),
+    rather than invoking a constructor.
+  */
+  bzero(&read_record, sizeof(read_record));
+}
+
+
+
 /* 
   Categories of data fields of variable length written into join cache buffers.
   The value of any of these fields is written into cache together with the


Attachment: [text/bzr-bundle] bzr/tor.didriksen@sun.com-20100614123758-hf26i35ewtfq6po5.bundle
Thread
bzr commit into mysql-next-mr-opt-backporting branch (tor.didriksen:3197)Bug#52538Tor Didriksen14 Jun
  • Re: bzr commit into mysql-next-mr-opt-backporting branch(tor.didriksen:3197) Bug#52538Guilhem Bichot14 Jun
    • Re: bzr commit into mysql-next-mr-opt-backporting branch(tor.didriksen:3197) Bug#52538Tor Didriksen14 Jun
      • Re: bzr commit into mysql-next-mr-opt-backporting branch(tor.didriksen:3197) Bug#52538Guilhem Bichot14 Jun
        • Re: bzr commit into mysql-next-mr-opt-backporting branch(tor.didriksen:3197) Bug#52538Tor Didriksen15 Jun
          • Re: bzr commit into mysql-next-mr-opt-backporting branch(tor.didriksen:3197) Bug#52538Guilhem Bichot15 Jun