summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <sanja@montyprogram.com>2012-05-25 10:29:53 +0300
committerunknown <sanja@montyprogram.com>2012-05-25 10:29:53 +0300
commitf45784c8503d0bbe77f3aec351fc87ff536b19be (patch)
treeed6e0b6cc29483f0707c7ce7bb3abe666384fc9d /sql
parentd56f5dae1ef60468dd7497453bcdca9b653922ca (diff)
downloadmariadb-git-f45784c8503d0bbe77f3aec351fc87ff536b19be.tar.gz
Fix of LP bug#992380 + revise fix_fields about missing with_subselect collection
The problem is that some fix_fields do not call Item_func::fix_fields and do not collect with subselect_information.
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc38
-rw-r--r--sql/item_cmpfunc.h3
2 files changed, 41 insertions, 0 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index dda9ab418a4..61554bdf420 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -4271,6 +4271,22 @@ Item_cond::fix_fields(THD *thd, Item **ref)
if (abort_on_null)
item->top_level_item();
+ /*
+ replace degraded condition:
+ was: <field>
+ become: <field> = 1
+ */
+ if (item->type() == FIELD_ITEM)
+ {
+ Query_arena backup, *arena;
+ Item *new_item;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ if ((new_item= new Item_func_ne(item, new Item_int(0, 1))))
+ li.replace(item= new_item);
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ }
+
// item can be substituted in fix_fields
if ((!item->fixed &&
item->fix_fields(thd, li.ref())) ||
@@ -5283,6 +5299,28 @@ Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */
}
+bool Item_func_not::fix_fields(THD *thd, Item **ref)
+{
+ if (args[0]->type() == FIELD_ITEM)
+ {
+ /* replace "NOT <field>" with "<filed> == 0" */
+ Query_arena backup, *arena;
+ Item *new_item;
+ bool rc= TRUE;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ if ((new_item= new Item_func_eq(args[0], new Item_int(0, 1))))
+ {
+ new_item->name= name;
+ rc= (*ref= new_item)->fix_fields(thd, ref);
+ }
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ return rc;
+ }
+ return Item_func::fix_fields(thd, ref);
+}
+
+
Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
{
Item *item= negated_item();
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 25b636397a8..7239079c56f 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -413,6 +413,7 @@ public:
enum Functype functype() const { return NOT_FUNC; }
const char *func_name() const { return "not"; }
Item *neg_transformer(THD *thd);
+ bool fix_fields(THD *, Item **);
virtual void print(String *str, enum_query_type query_type);
};
@@ -479,6 +480,8 @@ public:
longlong val_int();
enum Functype functype() const { return NOT_ALL_FUNC; }
const char *func_name() const { return "<not>"; }
+ bool fix_fields(THD *thd, Item **ref)
+ {return Item_func::fix_fields(thd, ref);}
virtual void print(String *str, enum_query_type query_type);
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };