diff options
author | unknown <sanja@askmonty.org> | 2011-11-13 12:02:13 +0200 |
---|---|---|
committer | unknown <sanja@askmonty.org> | 2011-11-13 12:02:13 +0200 |
commit | f76bfc40ea697473e7f1bea211a68a22210e7b53 (patch) | |
tree | a2bd573afac2d9f2c60ed30a3ea03929eb81f296 /sql | |
parent | 3fb60b1df089b5c4df27b6039d1013039bde84e5 (diff) | |
download | mariadb-git-f76bfc40ea697473e7f1bea211a68a22210e7b53.tar.gz |
Fix for LP BUG#824425: Prohibiting subqueries in rows for left part of IN/ALL/ANY
Fix for walk() method of subqueries: always call the method on the subquery.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 1 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 9 | ||||
-rw-r--r-- | sql/item_subselect.cc | 2 | ||||
-rw-r--r-- | sql/item_subselect.h | 1 |
4 files changed, 12 insertions, 1 deletions
diff --git a/sql/item.h b/sql/item.h index fa6918d8484..b858d8ce587 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1023,6 +1023,7 @@ public: virtual bool view_used_tables_processor(uchar *arg) { return 0; } virtual bool eval_not_null_tables(uchar *opt_arg) { return 0; } virtual bool clear_sum_processor(uchar *opt_arg) { return 0; } + virtual bool is_subquery_processor (uchar *opt_arg) { return 0; } /* To call bool function for all arguments */ struct bool_func_call_args diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a33dd090f14..5b2c862e9eb 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1436,6 +1436,7 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) cache->setup(args[0]); if (cache->cols() == 1) { + DBUG_ASSERT(args[0]->type() != ROW_ITEM); if ((used_tables_cache= args[0]->used_tables())) cache->set_used_tables(OUTER_REF_TABLE_BIT); else @@ -1446,6 +1447,14 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) uint n= cache->cols(); for (uint i= 0; i < n; i++) { + /* Check that the expression (part of row) do not contain a subquery */ + if (args[0]->element_index(i)->walk(&Item::is_subquery_processor, + FALSE, NULL)) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), + "SUBQUERY in ROW in left expression of IN/ALL/ANY"); + return 1; + } if (args[0]->element_index(i)->used_tables()) ((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT); else diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 6134903fee6..71408528903 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -528,7 +528,7 @@ bool Item_subselect::walk(Item_processor processor, bool walk_subquery, invalidated by irreversible cleanups (those happen after an uncorrelated subquery has been executed). */ - return FALSE; + return (this->*processor)(argument); } if (walk_subquery) diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 0ec0969e0ae..2012306c0f7 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -226,6 +226,7 @@ public: const char *func_name() const { DBUG_ASSERT(0); return "subselect"; } virtual bool expr_cache_is_needed(THD *); virtual void get_cache_parameters(List<Item> ¶meters); + virtual bool is_subquery_processor (uchar *opt_arg) { return 1; } friend class select_result_interceptor; friend class Item_in_optimizer; |