summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2010-02-21 05:36:18 +0200
committerSergey Petrunya <psergey@askmonty.org>2010-02-21 05:36:18 +0200
commit8f02e87d2ad3c880f248a533c3ba1b55ee11b077 (patch)
treebb366ae9d1d76506ab84d98bf96fa84b855f9681
parent7eb71ffc5ad66f60865402375ed59319b2eee6d2 (diff)
downloadmariadb-git-8f02e87d2ad3c880f248a533c3ba1b55ee11b077.tar.gz
* Better self-recursion protection in Item_subselect::fix_fields.
Don't go into branch that calls upper_refs.empty() more than once per PREPARE or EXECUTE * Avoid crashing when processing references to outside from subquery's HAVING (will explain in more details in email) sql/item.h: * Avoid crashing when processing references to outside from subquery's HAVING (will explain in more details in email) sql/item_subselect.cc: * Better self-recursion protection in Item_subselect::fix_fields. Don't go into branch that calls upper_refs.empty() more than once per PREPARE or EXECUTE
-rw-r--r--sql/item.h7
-rw-r--r--sql/item_subselect.cc6
2 files changed, 11 insertions, 2 deletions
diff --git a/sql/item.h b/sql/item.h
index 7cea03bf46d..19c03d19f73 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2378,7 +2378,12 @@ public:
return ref ? (*ref)->real_item() : this;
}
bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
- { return (*ref)->walk(processor, walk_subquery, arg); }
+ {
+ if (ref && *ref)
+ return (*ref)->walk(processor, walk_subquery, arg);
+ else
+ return FALSE;
+ }
bool enumerate_field_refs_processor(uchar *arg)
{ return (*ref)->enumerate_field_refs_processor(arg); }
virtual void print(String *str, enum_query_type query_type);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 122a3f70db4..61e72bc6ccc 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -186,7 +186,6 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
changed= 1;
inside_first_fix_fields= FALSE;
- done_first_fix_fields= FALSE;
if (!res)
{
@@ -218,12 +217,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (!(*ref)->fixed)
ret= (*ref)->fix_fields(thd, ref);
thd->where= save_where;
+ done_first_fix_fields= FALSE;
return ret;
}
// Is it one field subselect?
if (engine->cols() > max_columns)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
+ done_first_fix_fields= FALSE;
return TRUE;
}
fix_length_and_dec();
@@ -240,6 +241,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
fixed= 1;
err:
+ done_first_fix_fields= FALSE;
thd->where= save_where;
return res;
}
@@ -282,6 +284,7 @@ bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
return FALSE;
}
+
/*
Adjust attributes after our parent select has been merged into grandparent
@@ -310,6 +313,7 @@ void Item_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
parent_select= new_parent;
}
+
class Field_fixer: public Field_enumerator
{
public: