diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2010-02-21 05:36:18 +0200 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2010-02-21 05:36:18 +0200 |
commit | 8f02e87d2ad3c880f248a533c3ba1b55ee11b077 (patch) | |
tree | bb366ae9d1d76506ab84d98bf96fa84b855f9681 | |
parent | 7eb71ffc5ad66f60865402375ed59319b2eee6d2 (diff) | |
download | mariadb-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.h | 7 | ||||
-rw-r--r-- | sql/item_subselect.cc | 6 |
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: |