← Back to team overview

maria-developers team mailing list archive

Rev 2795: Bugfixes in file:///home/bell/maria/bzr/work-maria-5.3-scache/

 

At file:///home/bell/maria/bzr/work-maria-5.3-scache/

------------------------------------------------------------
revno: 2795
revision-id: sanja@xxxxxxxxxxxx-20100605195727-7rrc5k75lr0a4o9z
parent: sanja@xxxxxxxxxxxx-20100527182744-1tu96cgyiaodzs32
committer: sanja@xxxxxxxxxxxx
branch nick: work-maria-5.3-scache
timestamp: Sat 2010-06-05 22:57:27 +0300
message:
  Bugfixes
=== modified file 'mysql-test/r/myisam_mrr.result'
--- a/mysql-test/r/myisam_mrr.result	2010-03-11 21:43:31 +0000
+++ b/mysql-test/r/myisam_mrr.result	2010-06-05 19:57:27 +0000
@@ -394,7 +394,7 @@
 #   - engine_condition_pushdown does not affect ICP
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on
 create table t0 (a int);
 insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
 create table t1 (a int, b int, key(a));

=== modified file 'mysql-test/r/subquery_cache.result'
--- a/mysql-test/r/subquery_cache.result	2010-05-27 17:41:38 +0000
+++ b/mysql-test/r/subquery_cache.result	2010-06-05 19:57:27 +0000
@@ -588,4 +588,28 @@
 Subquery_cache_hit	0
 Subquery_cache_miss	4
 drop table t1;
+#test of sql_big_tables switch and outer table reference in subquery with grouping
+set option sql_big_tables=1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
+INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3);
+SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer;
+(SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1)
+1
+2
+3
+4
+5
+6
+drop table t1;
+set option sql_big_tables=0;
+#test of function reference to outer query
+set local group_concat_max_len=400;
+create table t2 (a int, b int);
+insert into t2 values (1,1), (2,2);
+select  b x, (select group_concat(x) from t2) from  t2;
+x	(select group_concat(x) from t2)
+1	1,1
+2	2,2
+drop table t2;
+set local group_concat_max_len=default;
 set optimizer_switch='subquery_cache=default';

=== modified file 'mysql-test/t/subquery_cache.test'
--- a/mysql-test/t/subquery_cache.test	2010-05-27 17:41:38 +0000
+++ b/mysql-test/t/subquery_cache.test	2010-06-05 19:57:27 +0000
@@ -201,4 +201,20 @@
 show status like "subquery_cache%";
 drop table t1;
 
+--echo #test of sql_big_tables switch and outer table reference in subquery with grouping
+set option sql_big_tables=1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
+INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3);
+SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1) FROM t1 AS t1_outer;
+drop table t1;
+set option sql_big_tables=0;
+
+--echo #test of function reference to outer query
+set local group_concat_max_len=400;
+create table t2 (a int, b int);
+insert into t2 values (1,1), (2,2);
+select  b x, (select group_concat(x) from t2) from  t2;
+drop table t2;
+set local group_concat_max_len=default;
+
 set optimizer_switch='subquery_cache=default';

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2010-05-27 17:41:38 +0000
+++ b/sql/item.cc	2010-06-05 19:57:27 +0000
@@ -5110,6 +5110,19 @@
 }
 
 
+/**
+  Saves one Fields of an Item of in other Field
+
+  @param from            Field to copy value from
+  @param null_value      reference on item null_value to set it if it is needed
+  @param to              Field to cope value to
+  @param no_conversions  how to deal with NULL value (see
+                         set_field_to_null_with_conversions())
+
+  @retval FALSE OK
+  @retval TRUE  Error
+*/
+
 static int save_field_in_field(Field *from, my_bool *null_value,
                                Field *to, bool no_conversions)
 {
@@ -5139,6 +5152,10 @@
 
 int Item_field::save_in_field(Field *to, bool no_conversions)
 {
+  /* if it is external field */
+  if (unlikely(depended_from))
+    return save_field_in_field(field, &null_value, to, no_conversions);
+
   return  save_field_in_field(result_field, &null_value, to, no_conversions);
 }
 
@@ -6346,7 +6363,7 @@
 int Item_ref::save_in_field(Field *to, bool no_conversions)
 {
   int res;
-  if (result_field)
+  if (result_field && !depended_from)
     return save_field_in_field(result_field, &null_value, to, no_conversions);
   res= (*ref)->save_in_field(to, no_conversions);
   null_value= (*ref)->null_value;

=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc	2010-05-25 18:29:14 +0000
+++ b/sql/item_subselect.cc	2010-06-05 19:57:27 +0000
@@ -1,4 +1,4 @@
-/* Copyrigh (C) 2000 MySQL AB
+/* Copyright (C) 2000 MySQL AB
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -818,6 +818,12 @@
   exec();
 }
 
+/**
+  Checks subquery cache for value
+
+  @retval NULL nothing found
+  @retval reference on item representing value found in the cache
+*/
 
 Item *Item_subselect::check_cache()
 {

=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h	2010-05-24 17:29:56 +0000
+++ b/sql/item_subselect.h	2010-06-05 19:57:27 +0000
@@ -95,7 +95,10 @@
   st_select_lex *parent_select;
 
   /**
-     List of items subquery depends on (externally resolved);
+     List of references on items subquery depends on (externally resolved);
+
+     @note We can't store direct links on Items because it could be
+           substituted with other item (for example for grouping).
    */
   List<Item*> depends_on;
 

=== modified file 'sql/sql_subquery_cache.cc'
--- a/sql/sql_subquery_cache.cc	2010-05-27 18:27:44 +0000
+++ b/sql/sql_subquery_cache.cc	2010-06-05 19:57:27 +0000
@@ -96,6 +96,10 @@
 /**
   Creates equalities expression.
 
+  @note For some type of fields index lookup do not return failure but set
+  pointer on the next record. To check exact match we use expression like:
+  field1=value1 and field2=value2 ...
+
   @retval FALSE OK
   @retval TRUE  Error
 */
@@ -111,6 +115,7 @@
   for (uint i= 1 /* skip result filed */; (ref= li++); i++)
   {
     Field *fld= cache_table->field[i];
+    /* Only some field types should be checked after lookup */
     if (fld->type() == MYSQL_TYPE_VARCHAR ||
         fld->type() == MYSQL_TYPE_TINY_BLOB ||
         fld->type() == MYSQL_TYPE_MEDIUM_BLOB ||
@@ -140,11 +145,22 @@
 }
 
 
+/**
+  Enumerates all fields in field number order.
+
+  @param arg             reference on current field number
+
+  @return field number
+*/
+
 static uint field_enumerator(uchar *arg)
 {
   return ((uint*)arg)[0]++;
 }
 
+/**
+  Initializes temporary table and index for this cache
+*/
 
 void Subquery_cache_tmptable::init()
 {
@@ -182,8 +198,10 @@
   if (!(cache_table= create_tmp_table(table_thd, &cache_table_param,
                                       items, (ORDER*) NULL,
                                       FALSE, FALSE,
-                                      (table_thd->options |
-                                       TMP_TABLE_ALL_COLUMNS),
+                                      ((table_thd->options |
+                                        TMP_TABLE_ALL_COLUMNS) &
+                                       ~(OPTION_BIG_TABLES |
+                                         TMP_TABLE_FORCE_MYISAM)),
                                       HA_POS_ERROR,
                                       (char *)"subquery-cache-table")))
   {
@@ -191,14 +209,16 @@
     DBUG_VOID_RETURN;
   }
 
-  if (cache_table->s->blob_fields)
+  if (cache_table->s->db_type() != heap_hton)
   {
-    DBUG_PRINT("error", ("we do not need blobs"));
+    DBUG_PRINT("error", ("we need only heap table"));
     goto error;
   }
 
+  /* first field in the table is result value, so we skip it */
   li_items++;
   field_counter=1;
+
   if (cache_table->alloc_keys(1) ||
       (cache_table->add_tmp_key(0, items.elements - 1,
                                 &field_enumerator,
@@ -224,6 +244,7 @@
     DBUG_PRINT("error", ("Creating Item_field failed"));
     goto error;
   }
+
   if (make_equalities())
   {
     DBUG_PRINT("error", ("Creating equalities failed"));
@@ -247,11 +268,26 @@
 }
 
 
+/**
+  Checks if current key present in the cache and returns value if it is true
+
+  @param value           assigned Item with value from the cache if key
+                         is found
+  @return result of the key lookup
+*/
+
 Subquery_cache::result Subquery_cache_tmptable::check_value(Item **value)
 {
   int res;
   DBUG_ENTER("Subquery_cache_tmptable::check_value");
 
+  /*
+    We delay cache initialization to get item references which should be
+    used at the moment of query execution. I.e. we store reference on item
+    reference at the moment of class creation but for table creation and
+    index supply structures (join_tab) we need real Items which used at the
+    moment of execution so we can resolve reference only at this point.
+  */
   if (!inited)
     init();
 
@@ -275,6 +311,15 @@
 }
 
 
+/**
+  Puts given value in the cache
+
+  @param value           Value to put in the cache
+
+  @retval FALSE OK
+  @retval TRUE  Error
+*/
+
 my_bool Subquery_cache_tmptable::put_value(Item *value)
 {
   int error;
@@ -313,9 +358,3 @@
   cache_table= NULL;
   DBUG_RETURN(TRUE);
 }
-
-
-void Subquery_cache_tmptable::cleanup()
-{
-  cache_table->file->ha_delete_all_rows();
-}

=== modified file 'sql/sql_subquery_cache.h'
--- a/sql/sql_subquery_cache.h	2010-05-25 10:45:36 +0000
+++ b/sql/sql_subquery_cache.h	2010-06-05 19:57:27 +0000
@@ -23,10 +23,6 @@
     Puts value into this cache (key should be taken from cache owner)
   */
   virtual my_bool put_value(Item *value)= 0;
-  /**
-    Cleans up and reset cache before reusing
-  */
-  virtual void cleanup()= 0;
 };
 
 struct st_table_ref;
@@ -45,10 +41,9 @@
   virtual ~Subquery_cache_tmptable();
   virtual result check_value(Item **value);
   virtual my_bool put_value(Item *value);
-  virtual void cleanup();
+
+private:
   void init();
-
-private:
   bool make_equalities();
 
   /* tmp table parameters */

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2010-05-27 17:41:38 +0000
+++ b/sql/table.cc	2010-06-05 19:57:27 +0000
@@ -5187,10 +5187,16 @@
     key_part_info->store_length= key_part_info->length;
 
     if ((*reg_field)->real_maybe_null())
+    {
       key_part_info->store_length+= HA_KEY_NULL_LENGTH;
+      keyinfo->key_length+= HA_KEY_NULL_LENGTH;
+    }
     if ((*reg_field)->type() == MYSQL_TYPE_BLOB || 
         (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
+    {
       key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
+      keyinfo->key_length+= HA_KEY_BLOB_LENGTH; // ???
+    }
 
     key_part_info->type=     (uint8) (*reg_field)->key_type();
     key_part_info->key_type =