diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2011-09-23 01:25:08 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2011-09-23 01:25:08 +0400 |
commit | ebbdb14a02daf36063effc8b734028578f7e4e90 (patch) | |
tree | 4502de918c214b3ba5633d6e632cd6cd9ba258b7 /sql | |
parent | 42b928ca05fca3ae8858566622a3a483a70aa3fc (diff) | |
download | mariadb-git-ebbdb14a02daf36063effc8b734028578f7e4e90.tar.gz |
BUG#849776: Wrong result with semijoin + "Impossible where"
- Provide fix_after_pullout() function for Item_in_optimizer and other Item_XXX classes (basically, all of them
that have eval_not_null_tables, which means they have special rules for calculating not_null_tables_cache value)
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.cc | 36 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 4 | ||||
-rw-r--r-- | sql/item_row.cc | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 3 |
4 files changed, 43 insertions, 2 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 91a656b645a..14faed3dcde 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1405,6 +1405,16 @@ bool Item_in_optimizer::is_top_level_item() } +void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref) +{ + /* This will re-calculate attributes of our Item_in_subselect: */ + Item_bool_func::fix_after_pullout(new_parent, ref); + + /* Then, re-calculate not_null_tables_cache: */ + eval_not_null_tables(NULL); +} + + bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg) { not_null_tables_cache= 0; @@ -2136,6 +2146,14 @@ bool Item_func_between::eval_not_null_tables(uchar *opt_arg) } +void Item_func_between::fix_after_pullout(st_select_lex *new_parent, Item **ref) +{ + /* This will re-calculate attributes of the arguments */ + Item_func_opt_neg::fix_after_pullout(new_parent, ref); + /* Then, re-calculate not_null_tables_cache according to our special rules */ + eval_not_null_tables(NULL); +} + void Item_func_between::fix_length_and_dec() { THD *thd= current_thd; @@ -2516,6 +2534,16 @@ Item_func_if::eval_not_null_tables(uchar *opt_arg) return 0; } + +void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref) +{ + /* This will re-calculate attributes of the arguments */ + Item_func::fix_after_pullout(new_parent, ref); + /* Then, re-calculate not_null_tables_cache according to our special rules */ + eval_not_null_tables(NULL); +} + + void Item_func_if::fix_length_and_dec() { @@ -3760,6 +3788,14 @@ Item_func_in::eval_not_null_tables(uchar *opt_arg) } +void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref) +{ + /* This will re-calculate attributes of the arguments */ + Item_func_opt_neg::fix_after_pullout(new_parent, ref); + /* Then, re-calculate not_null_tables_cache according to our special rules */ + eval_not_null_tables(NULL); +} + static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) { return cs->coll->strnncollsp(cs, diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index acbb7413459..81a18bb594e 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -262,6 +262,7 @@ public: virtual void get_cache_parameters(List<Item> ¶meters); bool is_top_level_item(); bool eval_not_null_tables(uchar *opt_arg); + void fix_after_pullout(st_select_lex *new_parent, Item **ref); }; class Comp_creator @@ -674,6 +675,7 @@ public: CHARSET_INFO *compare_collation() { return cmp_collation.collation; } uint decimal_precision() const { return 1; } bool eval_not_null_tables(uchar *opt_arg); + void fix_after_pullout(st_select_lex *new_parent, Item **ref); }; @@ -775,6 +777,7 @@ public: uint decimal_precision() const; const char *func_name() const { return "if"; } bool eval_not_null_tables(uchar *opt_arg); + void fix_after_pullout(st_select_lex *new_parent, Item **ref); }; @@ -1313,6 +1316,7 @@ public: bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp_collation.collation; } bool eval_not_null_tables(uchar *opt_arg); + void fix_after_pullout(st_select_lex *new_parent, Item **ref); }; class cmp_item_row :public cmp_item diff --git a/sql/item_row.cc b/sql/item_row.cc index 09977d71bb7..46d5f13f6fa 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -149,11 +149,13 @@ void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref) { used_tables_cache= 0; const_item_cache= 1; + not_null_tables_cache= 0; for (uint i= 0; i < arg_count; i++) { items[i]->fix_after_pullout(new_parent, &items[i]); used_tables_cache|= items[i]->used_tables(); const_item_cache&= items[i]->const_item(); + not_null_tables_cache|= items[i]->not_null_tables(); } } diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 50533c1a7ff..43df9fe32a9 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2477,8 +2477,7 @@ void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref) { left_expr->fix_after_pullout(new_parent, &left_expr); Item_subselect::fix_after_pullout(new_parent, ref); - //psergey-todo: the above looks odd, why don't we 'aggregate' left_expr with - //the rest? + used_tables_cache |= left_expr->used_tables(); } void Item_in_subselect::update_used_tables() |