Commit 2419ef96 authored by Sergey Petrunya's avatar Sergey Petrunya

* 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
parent 1f23508e
...@@ -2378,7 +2378,12 @@ class Item_ref :public Item_ident ...@@ -2378,7 +2378,12 @@ class Item_ref :public Item_ident
return ref ? (*ref)->real_item() : this; return ref ? (*ref)->real_item() : this;
} }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg) 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) bool enumerate_field_refs_processor(uchar *arg)
{ return (*ref)->enumerate_field_refs_processor(arg); } { return (*ref)->enumerate_field_refs_processor(arg); }
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
......
...@@ -186,7 +186,6 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) ...@@ -186,7 +186,6 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
changed= 1; changed= 1;
inside_first_fix_fields= FALSE; inside_first_fix_fields= FALSE;
done_first_fix_fields= FALSE;
if (!res) if (!res)
{ {
...@@ -218,12 +217,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) ...@@ -218,12 +217,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (!(*ref)->fixed) if (!(*ref)->fixed)
ret= (*ref)->fix_fields(thd, ref); ret= (*ref)->fix_fields(thd, ref);
thd->where= save_where; thd->where= save_where;
done_first_fix_fields= FALSE;
return ret; return ret;
} }
// Is it one field subselect? // Is it one field subselect?
if (engine->cols() > max_columns) if (engine->cols() > max_columns)
{ {
my_error(ER_OPERAND_COLUMNS, MYF(0), 1); my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
done_first_fix_fields= FALSE;
return TRUE; return TRUE;
} }
fix_length_and_dec(); fix_length_and_dec();
...@@ -240,6 +241,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) ...@@ -240,6 +241,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
fixed= 1; fixed= 1;
err: err:
done_first_fix_fields= FALSE;
thd->where= save_where; thd->where= save_where;
return res; return res;
} }
...@@ -282,6 +284,7 @@ bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select, ...@@ -282,6 +284,7 @@ bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
return FALSE; return FALSE;
} }
/* /*
Adjust attributes after our parent select has been merged into grandparent 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) ...@@ -310,6 +313,7 @@ void Item_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
parent_select= new_parent; parent_select= new_parent;
} }
class Field_fixer: public Field_enumerator class Field_fixer: public Field_enumerator
{ {
public: public:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment