summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <sanja@askmonty.org>2010-09-06 15:34:24 +0300
committerunknown <sanja@askmonty.org>2010-09-06 15:34:24 +0300
commitd6a9b52269c2f64a8f793c4680eed9adece0a716 (patch)
treea5f6b2b18651a0641556d5c1d6a0e7f3908e8f09 /sql
parent08d1de3732e50529318d533d5d83811b910ab9e9 (diff)
downloadmariadb-git-d6a9b52269c2f64a8f793c4680eed9adece0a716.tar.gz
Fixed LP BUG#615760: Check on double cache assignment added into the transformation methods.
Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/compare.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/group_by.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect3.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect3_jcl6.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect4.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect_cache.result: Added test suite for LP BUG#615760 mysql-test/r/subselect_mat.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect_no_mat.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect_no_opts.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect_no_semijoin.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect_sj.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/r/subselect_sj_jcl6.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/suite/pbxt/r/subselect.result: Cache parameters print added in EXPLAIN EXTENDED output. mysql-test/t/subselect_cache.test: Cache parameters print added in EXPLAIN EXTENDED output. sql/item.cc: Item::set_expr_cache result fixed according to its description. Cache parameters print added in EXPLAIN EXTENDED output. sql/item.h: Cache parameters print added in EXPLAIN EXTENDED output. sql/item_cmpfunc.cc: Check on double cache assignment added into the transformation methods. sql/item_cmpfunc.h: Check on double cache assignment added into the transformation methods. sql/item_subselect.cc: Check on double cache assignment added into the transformation methods. sql/item_subselect.h: Check on double cache assignment added into the transformation methods. sql/sql_expression_cache.cc: Cache parameters print added. sql/sql_expression_cache.h: Cache parameters print added. sql/sql_select.cc: Removed unused method (now it is impossible to make double transformation with the cache). sql/sql_select.h: Removed unused method.
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc17
-rw-r--r--sql/item.h8
-rw-r--r--sql/item_cmpfunc.cc11
-rw-r--r--sql/item_cmpfunc.h3
-rw-r--r--sql/item_subselect.cc26
-rw-r--r--sql/item_subselect.h4
-rw-r--r--sql/sql_expression_cache.cc18
-rw-r--r--sql/sql_expression_cache.h7
-rw-r--r--sql/sql_select.cc69
-rw-r--r--sql/sql_select.h2
10 files changed, 79 insertions, 86 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 1976b6f5015..8f393eca79b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -567,10 +567,10 @@ Item* Item::set_expr_cache(THD *thd, List<Item *> &depends_on)
!wrapper->fix_fields(thd, (Item**)&wrapper))
{
if (wrapper->set_cache(thd, depends_on))
- DBUG_RETURN(this);
+ DBUG_RETURN(NULL);
DBUG_RETURN(wrapper);
}
- DBUG_RETURN(this);
+ DBUG_RETURN(NULL);
}
@@ -6635,6 +6635,19 @@ Item_cache_wrapper::Item_cache_wrapper(Item *item_arg)
}
+void Item_cache_wrapper::print(String *str, enum_query_type query_type)
+{
+ str->append(func_name());
+ if (expr_cache)
+ expr_cache->print(str, query_type);
+ else
+ str->append(STRING_WITH_LEN("<<DISABLED>>"));
+ str->append('(');
+ orig_item->print(str, query_type);
+ str->append(')');
+}
+
+
/**
Prepare the expression cache wrapper (do nothing)
diff --git a/sql/item.h b/sql/item.h
index 4e26e526b7b..05e35e97e04 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2628,13 +2628,7 @@ public:
/* Following methods make this item transparent as much as possible */
- virtual void print(String *str, enum_query_type query_type)
- {
- str->append(func_name());
- str->append('(');
- orig_item->print(str, query_type);
- str->append(')');
- }
+ virtual void print(String *str, enum_query_type query_type);
virtual const char *full_name() const { return orig_item->full_name(); }
virtual void make_field(Send_field *field) { orig_item->make_field(field); }
bool eq(const Item *item, bool binary_cmp) const
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index d1ef5fb5264..6b075c2d4aa 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1774,6 +1774,9 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg)
DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
List<Item*> &depends_on= ((Item_subselect *)args[1])->depends_on;
+ if (expr_cache)
+ DBUG_RETURN(expr_cache);
+
/* Add left expression to the list of the parameters of the subquery */
if (args[0]->cols() == 1)
depends_on.push_front((Item**)args);
@@ -1785,8 +1788,11 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg)
}
}
- if (args[1]->expr_cache_is_needed(thd))
- DBUG_RETURN(set_expr_cache(thd, depends_on));
+ if (args[1]->expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd, depends_on)))
+ DBUG_RETURN(expr_cache);
+
+ depends_on.pop();
DBUG_RETURN(this);
}
@@ -1889,6 +1895,7 @@ void Item_in_optimizer::cleanup()
Item_bool_func::cleanup();
if (!save_cache)
cache= 0;
+ expr_cache= 0;
DBUG_VOID_RETURN;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 053a54349c2..2eb419738e3 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -242,6 +242,7 @@ class Item_in_optimizer: public Item_bool_func
{
protected:
Item_cache *cache;
+ Item *expr_cache;
bool save_cache;
/*
Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
@@ -252,7 +253,7 @@ protected:
my_bool result_for_null_param;
public:
Item_in_optimizer(Item *a, Item_in_subselect *b):
- Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
+ Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), expr_cache(0),
save_cache(0), result_for_null_param(UNKNOWN)
{}
bool fix_fields(THD *, Item **);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 7f5f0fd51f1..814bf14bb3e 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -34,11 +34,10 @@
Item_subselect::Item_subselect():
Item_result_field(), value_assigned(0), thd(0), substitution(0),
- engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
- const_item_cache(1),
- inside_first_fix_fields(0), done_first_fix_fields(FALSE),
- eliminated(FALSE),
- engine_changed(0), changed(0), is_correlated(FALSE)
+ expr_cache(0), engine(0), old_engine(0), used_tables_cache(0),
+ have_to_be_excluded(0), const_item_cache(1), inside_first_fix_fields(0),
+ done_first_fix_fields(FALSE), eliminated(FALSE), engine_changed(0),
+ changed(0), is_correlated(FALSE)
{
with_subselect= 1;
reset();
@@ -121,6 +120,7 @@ void Item_subselect::cleanup()
depends_on.empty();
reset();
value_assigned= 0;
+ expr_cache= 0;
DBUG_VOID_RETURN;
}
@@ -861,8 +861,12 @@ Item* Item_singlerow_subselect::expr_cache_insert_transformer(uchar *thd_arg)
THD *thd= (THD*) thd_arg;
DBUG_ENTER("Item_singlerow_subselect::expr_cache_insert_transformer");
- if (expr_cache_is_needed(thd))
- DBUG_RETURN(set_expr_cache(thd, depends_on));
+ if (expr_cache)
+ DBUG_RETURN(expr_cache);
+
+ if (expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd, depends_on)))
+ DBUG_RETURN(expr_cache);
DBUG_RETURN(this);
}
@@ -1083,8 +1087,12 @@ Item* Item_exists_subselect::expr_cache_insert_transformer(uchar *thd_arg)
THD *thd= (THD*) thd_arg;
DBUG_ENTER("Item_exists_subselect::expr_cache_insert_transformer");
- if (substype() == EXISTS_SUBS && expr_cache_is_needed(thd))
- DBUG_RETURN(set_expr_cache(thd, depends_on));
+ if (expr_cache)
+ DBUG_RETURN(expr_cache);
+
+ if (substype() == EXISTS_SUBS && expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd, depends_on)))
+ DBUG_RETURN(expr_cache);
DBUG_RETURN(this);
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 72f73d58867..3b0a9075a20 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -53,6 +53,7 @@ public:
/* unit of subquery */
st_select_lex_unit *unit;
protected:
+ Item *expr_cache;
/* engine that perform execution of subselect (single select or union) */
subselect_engine *engine;
/* old engine if engine was changed */
@@ -214,7 +215,8 @@ protected:
Item_cache *value, **row;
public:
Item_singlerow_subselect(st_select_lex *select_lex);
- Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
+ Item_singlerow_subselect() :Item_subselect(), value(0), row (0)
+ {}
void cleanup();
subs_type substype() { return SINGLEROW_SUBS; }
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
index 9596ca87bab..cbbafbd55c8 100644
--- a/sql/sql_expression_cache.cc
+++ b/sql/sql_expression_cache.cc
@@ -314,3 +314,21 @@ err:
cache_table= NULL;
DBUG_RETURN(TRUE);
}
+
+
+void Expression_cache_tmptable::print(String *str, enum_query_type query_type)
+{
+ List_iterator<Item*> li(*list);
+ Item **item;
+ bool is_first= TRUE;
+
+ str->append('<');
+ while ((item= li++))
+ {
+ if (!is_first)
+ str->append(',');
+ (*item)->print(str, query_type);
+ is_first= FALSE;
+ }
+ str->append('>');
+}
diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h
index bb5dc7a76a2..e931eca6091 100644
--- a/sql/sql_expression_cache.h
+++ b/sql/sql_expression_cache.h
@@ -32,6 +32,11 @@ public:
into the expression cache
*/
virtual my_bool put_value(Item *value)= 0;
+
+ /**
+ Print cache parameters
+ */
+ virtual void print(String *str, enum_query_type query_type)= 0;
};
struct st_table_ref;
@@ -51,6 +56,8 @@ public:
virtual result check_value(Item **value);
virtual my_bool put_value(Item *value);
+ void print(String *str, enum_query_type query_type);
+
private:
void init();
bool make_equalities();
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2638daf4e5c..09d8be97eb4 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1517,63 +1517,6 @@ setup_subq_exit:
/**
- Transform given item with changing it in all_fields if it is needed.
-
- @param expr Reference on expression to transform
- @param transformer Transformer to apply to the expression
-
- @details
- The function transforms the expression expr and, if the top item of the
- expression has changed, the function looks for the item in
- JOIN::all_fields and replaces it with the result of transformation.
-*/
-
-void JOIN::transform_and_change_in_all_fields(Item** expr,
- Item_transformer transformer)
-{
- DBUG_ENTER("JOIN::transform_and_change_in_all_fields");
- Item *new_item= (*expr)->transform(transformer,
- (uchar*) thd);
- if (new_item != (*expr))
- {
- List_iterator<Item> li(all_fields);
- Item *it;
-
- /*
- Check if this item already has expression cache and if it has then use
- that cache instead of the cache we have just created
- */
- while ((it= li++))
- {
- if (((*expr) == it->get_cached_item()))
- {
- /*
- We have to forget about the created cache, but this situation is
- really rare.
- */
- new_item->cleanup();
- new_item= it;
- DBUG_PRINT("info", ("Other cache found"));
- break;
- }
- }
-
- li.rewind();
- while ((it= li++))
- {
- if (it == (*expr))
- {
- li.replace(new_item);
- DBUG_PRINT("info", ("Cache Added"));
- }
- }
- *expr= new_item;
- }
- DBUG_VOID_RETURN;
-}
-
-
-/**
Setup expression caches for subqueries that need them
@details
@@ -1633,7 +1576,7 @@ bool JOIN::setup_subquery_caches()
select_lex->expr_cache_may_be_used[IN_GROUP_BY] ||
select_lex->expr_cache_may_be_used[NO_MATTER])
{
- List_iterator<Item> li(fields_list);
+ List_iterator<Item> li(all_fields);
Item *item;
while ((item= li++))
{
@@ -1646,16 +1589,18 @@ bool JOIN::setup_subquery_caches()
}
for (ORDER *group= group_list; group ; group= group->next)
{
- transform_and_change_in_all_fields(group->item,
- &Item::expr_cache_insert_transformer);
+ *group->item=
+ (*group->item)->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
}
}
if (select_lex->expr_cache_may_be_used[NO_MATTER])
{
for (ORDER *ord= order; ord; ord= ord->next)
{
- transform_and_change_in_all_fields(ord->item,
- &Item::expr_cache_insert_transformer);
+ *ord->item=
+ (*ord->item)->transform(&Item::expr_cache_insert_transformer,
+ (uchar*) thd);
}
}
DBUG_RETURN(FALSE);
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 2b7fc8fd47c..affa0fd3ed4 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1742,8 +1742,6 @@ private:
*/
bool implicit_grouping;
bool make_simple_join(JOIN *join, TABLE *tmp_table);
- void transform_and_change_in_all_fields(Item** item,
- Item_transformer transformer);
};