diff options
author | unknown <sanja@askmonty.org> | 2010-09-06 15:34:24 +0300 |
---|---|---|
committer | unknown <sanja@askmonty.org> | 2010-09-06 15:34:24 +0300 |
commit | d6a9b52269c2f64a8f793c4680eed9adece0a716 (patch) | |
tree | a5f6b2b18651a0641556d5c1d6a0e7f3908e8f09 /sql | |
parent | 08d1de3732e50529318d533d5d83811b910ab9e9 (diff) | |
download | mariadb-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.cc | 17 | ||||
-rw-r--r-- | sql/item.h | 8 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 11 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 3 | ||||
-rw-r--r-- | sql/item_subselect.cc | 26 | ||||
-rw-r--r-- | sql/item_subselect.h | 4 | ||||
-rw-r--r-- | sql/sql_expression_cache.cc | 18 | ||||
-rw-r--r-- | sql/sql_expression_cache.h | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 69 | ||||
-rw-r--r-- | sql/sql_select.h | 2 |
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); }; |