summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <sanja@askmonty.org>2011-11-13 12:02:13 +0200
committerunknown <sanja@askmonty.org>2011-11-13 12:02:13 +0200
commitf76bfc40ea697473e7f1bea211a68a22210e7b53 (patch)
treea2bd573afac2d9f2c60ed30a3ea03929eb81f296 /sql
parent3fb60b1df089b5c4df27b6039d1013039bde84e5 (diff)
downloadmariadb-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.h1
-rw-r--r--sql/item_cmpfunc.cc9
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/item_subselect.h1
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> &parameters);
+ virtual bool is_subquery_processor (uchar *opt_arg) { return 1; }
friend class select_result_interceptor;
friend class Item_in_optimizer;