diff options
author | Igor Babaev <igor@askmonty.org> | 2017-06-22 00:41:44 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2017-06-22 22:06:03 -0700 |
commit | 9f3622191df074d9f4e512320effe86f06b250fb (patch) | |
tree | 16aadc76e982cb17349df79a381af23fec27b2f8 /sql/item.h | |
parent | a8131e71f9504a7399bc9a7f312b14ed6700d099 (diff) | |
download | mariadb-git-9f3622191df074d9f4e512320effe86f06b250fb.tar.gz |
Fixed the bug mdev-12845.
This patch fills in a serious flaw in the
code that supports condition pushdown into
materialized views / derived tables.
If a predicate happened to contain a reference
to a mergeable view / derived table and it does
not depended directly on the target materialized
view / derived table then the predicate was not
considered as a subject to pusdown to this view
/ derived table.
Diffstat (limited to 'sql/item.h')
-rw-r--r-- | sql/item.h | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/sql/item.h b/sql/item.h index 5ed3e8acb82..02e4b2e3468 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1580,8 +1580,20 @@ public: virtual bool limit_index_condition_pushdown_processor(void *arg) { return 0; } virtual bool exists2in_processor(void *arg) { return 0; } virtual bool find_selective_predicates_list_processor(void *arg) { return 0; } - virtual bool exclusive_dependence_on_table_processor(void *arg) { return 0; } - virtual bool exclusive_dependence_on_grouping_fields_processor(void *arg) { return 0; } + + /* + TRUE if the expression depends only on the table indicated by tab_map + or can be converted to such an exression using equalities. + Not to be used for AND/OR formulas. + */ + virtual bool excl_dep_on_table(table_map tab_map) { return false; } + /* + TRUE if the expression depends only on grouping fields of sel + or can be converted to such an exression using equalities. + Not to be used for AND/OR formulas. + */ + virtual bool excl_dep_on_grouping_fields(st_select_lex *sel) { return false; } + virtual bool switch_to_nullable_fields_processor(void *arg) { return 0; } virtual bool find_function_processor (void *arg) { return 0; } /* @@ -2633,8 +2645,8 @@ public: Item *derived_field_transformer_for_where(THD *thd, uchar *arg); Item *derived_grouping_field_transformer_for_where(THD *thd, uchar *arg); virtual void print(String *str, enum_query_type query_type); - bool exclusive_dependence_on_table_processor(void *map); - bool exclusive_dependence_on_grouping_fields_processor(void *arg); + bool excl_dep_on_table(table_map tab_map); + bool excl_dep_on_grouping_fields(st_select_lex *sel); bool cleanup_excluding_fields_processor(void *arg) { return field ? 0 : cleanup_processor(arg); } bool cleanup_excluding_const_fields_processor(void *arg) @@ -3853,6 +3865,28 @@ protected: } bool transform_args(THD *thd, Item_transformer transformer, uchar *arg); void propagate_equal_fields(THD *, const Item::Context &, COND_EQUAL *); + bool excl_dep_on_table(table_map tab_map) + { + for (uint i= 0; i < arg_count; i++) + { + if (args[i]->const_item()) + continue; + if (!args[i]->excl_dep_on_table(tab_map)) + return false; + } + return true; + } + bool excl_dep_on_grouping_fields(st_select_lex *sel) + { + for (uint i= 0; i < arg_count; i++) + { + if (args[i]->const_item()) + continue; + if (!args[i]->excl_dep_on_grouping_fields(sel)) + return false; + } + return true; + } public: Item_args(void) :args(NULL), arg_count(0) @@ -4321,10 +4355,15 @@ public: } Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return get_item_copy<Item_ref>(thd, mem_root, this); } - bool exclusive_dependence_on_table_processor(void *map) - { return depended_from != NULL; } - bool exclusive_dependence_on_grouping_fields_processor(void *arg) - { return depended_from != NULL; } + bool excl_dep_on_table(table_map tab_map) + { + table_map used= used_tables(); + if (used & OUTER_REF_TABLE_BIT) + return false; + return (used == tab_map) || (*ref)->excl_dep_on_table(tab_map); + } + bool excl_dep_on_grouping_fields(st_select_lex *sel) + { return (*ref)->excl_dep_on_grouping_fields(sel); } bool cleanup_excluding_fields_processor(void *arg) { Item *item= real_item(); @@ -4621,13 +4660,20 @@ public: return (*ref)->walk(processor, walk_subquery, arg) || (this->*processor)(arg); } - bool view_used_tables_processor(void *arg) + bool view_used_tables_processor(void *arg) { TABLE_LIST *view_arg= (TABLE_LIST *) arg; if (view_arg == view) view_arg->view_used_tables|= (*ref)->used_tables(); return 0; } + bool excl_dep_on_table(table_map tab_map); + bool excl_dep_on_grouping_fields(st_select_lex *sel); + Item *derived_field_transformer_for_having(THD *thd, uchar *arg); + Item *derived_field_transformer_for_where(THD *thd, uchar *arg); + Item *derived_grouping_field_transformer_for_where(THD *thd, + uchar *arg); + void save_val(Field *to) { if (check_null_ref()) @@ -4709,6 +4755,8 @@ public: item_equal= NULL; Item_direct_ref::cleanup(); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_direct_view_ref>(thd, mem_root, this); } }; |