maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #03225
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 =