diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2015-04-14 23:18:54 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2015-04-23 15:56:10 +0200 |
commit | 20109712aeb3d23e5e975780897ad236cbcd2ddc (patch) | |
tree | 1d6e7509cce9617bb40c8dcffc34b6cc810e1eb3 /sql | |
parent | 8cbaafd22b145512cc91f7b512290320849e77bd (diff) | |
download | mariadb-git-20109712aeb3d23e5e975780897ad236cbcd2ddc.tar.gz |
MDEV-6892: WHERE does not apply
Taking into account implicit dependence of constant view field from nullable table of left join added.
Fixed finding real table to check if it turned to NULL (materialized view & derived taken into account)
Removed incorrect uninitialization.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 26 | ||||
-rw-r--r-- | sql/item.h | 24 | ||||
-rw-r--r-- | sql/table.cc | 42 |
3 files changed, 58 insertions, 34 deletions
diff --git a/sql/item.cc b/sql/item.cc index cfc5f67dc8e..59ec3e69102 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7949,6 +7949,7 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference) return TRUE; if (view->table && view->table->maybe_null) maybe_null= TRUE; + set_null_ref_table(); return FALSE; } @@ -9790,13 +9791,28 @@ void Item_ref::update_used_tables() (*ref)->update_used_tables(); } +void Item_direct_view_ref::update_used_tables() +{ + set_null_ref_table(); + Item_direct_ref::update_used_tables(); +} + + table_map Item_direct_view_ref::used_tables() const { - return get_depended_from() ? - OUTER_REF_TABLE_BIT : - ((view->is_merged_derived() || view->merged || !view->table) ? - (*ref)->used_tables() : - view->table->map); + DBUG_ASSERT(null_ref_table); + + if (get_depended_from()) + return OUTER_REF_TABLE_BIT; + + if (view->is_merged_derived() || view->merged || !view->table) + return ((*ref)->used_tables() ? + (*ref)->used_tables() : + ((null_ref_table != NO_NULL_TABLE) ? + null_ref_table->map : + (table_map)0 )); + + return view->table->map; } table_map Item_direct_view_ref::not_null_tables() const diff --git a/sql/item.h b/sql/item.h index ed50605ef7b..2d7236615a8 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3315,13 +3315,16 @@ class Item_direct_view_ref :public Item_direct_ref #define NO_NULL_TABLE (reinterpret_cast<TABLE *>(0x1)) + void set_null_ref_table() + { + if (!view->is_inner_table_of_outer_join() || + !(null_ref_table= view->get_real_join_table())) + null_ref_table= NO_NULL_TABLE; + } + bool check_null_ref() { - if (null_ref_table == NULL) - { - if (!(null_ref_table= view->get_real_join_table())) - null_ref_table= NO_NULL_TABLE; - } + DBUG_ASSERT(null_ref_table); if (null_ref_table != NO_NULL_TABLE && null_ref_table->null_row) { null_value= 1; @@ -3329,6 +3332,7 @@ class Item_direct_view_ref :public Item_direct_ref } return FALSE; } + public: Item_direct_view_ref(Name_resolution_context *context_arg, Item **item, const char *table_name_arg, @@ -3336,7 +3340,11 @@ public: TABLE_LIST *view_arg) :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg), item_equal(0), view(view_arg), - null_ref_table(NULL) {} + null_ref_table(NULL) + { + if (fixed) + set_null_ref_table(); + } bool fix_fields(THD *, Item **); bool eq(const Item *item, bool binary_cmp) const; @@ -3353,8 +3361,10 @@ public: bool subst_argument_checker(uchar **arg); Item *equal_fields_propagator(uchar *arg); Item *replace_equal_field(uchar *arg); - table_map used_tables() const; + table_map used_tables() const; + void update_used_tables(); table_map not_null_tables() const; + bool const_item() const { return used_tables() == 0; } bool walk(Item_processor processor, bool walk_subquery, uchar *arg) { return (*ref)->walk(processor, walk_subquery, arg) || diff --git a/sql/table.cc b/sql/table.cc index 7df2ae641ca..e4dee77171d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5034,7 +5034,8 @@ TABLE *TABLE_LIST::get_real_join_table() TABLE_LIST *tbl= this; while (tbl->table == NULL || tbl->table->reginfo.join_tab == NULL) { - if (tbl->view == NULL && tbl->derived == NULL) + if ((tbl->view == NULL && tbl->derived == NULL) || + tbl->is_materialized_derived()) break; /* we do not support merging of union yet */ DBUG_ASSERT(tbl->view == NULL || @@ -5043,28 +5044,25 @@ TABLE *TABLE_LIST::get_real_join_table() tbl->derived->first_select()->next_select() == NULL); { - List_iterator_fast<TABLE_LIST> ti; + List_iterator_fast<TABLE_LIST> + ti(tbl->view != NULL ? + tbl->view->select_lex.top_join_list : + tbl->derived->first_select()->top_join_list); + for (;;) { - List_iterator_fast<TABLE_LIST> - ti(tbl->view != NULL ? - tbl->view->select_lex.top_join_list : - tbl->derived->first_select()->top_join_list); - for (;;) - { - tbl= NULL; - /* - Find left table in outer join on this level - (the list is reverted). - */ - for (TABLE_LIST *t= ti++; t; t= ti++) - tbl= t; - if (!tbl) - return NULL; // view/derived with no tables - if (!tbl->nested_join) - break; - /* go deeper if we've found nested join */ - ti= tbl->nested_join->join_list; - } + tbl= NULL; + /* + Find left table in outer join on this level + (the list is reverted). + */ + for (TABLE_LIST *t= ti++; t; t= ti++) + tbl= t; + if (!tbl) + return NULL; // view/derived with no tables + if (!tbl->nested_join) + break; + /* go deeper if we've found nested join */ + ti= tbl->nested_join->join_list; } } } |