summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2011-09-23 01:25:08 +0400
committerSergey Petrunya <psergey@askmonty.org>2011-09-23 01:25:08 +0400
commitebbdb14a02daf36063effc8b734028578f7e4e90 (patch)
tree4502de918c214b3ba5633d6e632cd6cd9ba258b7 /sql
parent42b928ca05fca3ae8858566622a3a483a70aa3fc (diff)
downloadmariadb-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.cc36
-rw-r--r--sql/item_cmpfunc.h4
-rw-r--r--sql/item_row.cc2
-rw-r--r--sql/item_subselect.cc3
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> &parameters);
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()