summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_system.result2
-rw-r--r--mysql-test/r/subselect.result8
-rw-r--r--mysql-test/t/subselect.test10
-rw-r--r--sql/item_subselect.cc44
-rw-r--r--sql/item_subselect.h10
-rw-r--r--sql/sql_prepare.cc1
6 files changed, 47 insertions, 28 deletions
diff --git a/mysql-test/r/func_system.result b/mysql-test/r/func_system.result
index 671132428c5..d3db2cc5151 100644
--- a/mysql-test/r/func_system.result
+++ b/mysql-test/r/func_system.result
@@ -46,7 +46,7 @@ create table t1 (version char(40)) select database(), user(), version() as 'vers
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `database()` char(34) character set utf8 NOT NULL default '',
+ `database()` char(34) character set utf8 default NULL,
`user()` char(77) character set utf8 NOT NULL default '',
`version` char(40) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 5ab36dacaaf..77339473142 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1891,3 +1891,11 @@ abc b
3 4
deallocate prepare stmt1;
DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+a C
+1 1
+drop table t1,t2;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 0c093c4ae3e..eb4b1f33b14 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1212,3 +1212,13 @@ execute stmt1;
select * from t3;
deallocate prepare stmt1;
DROP TABLE t1, t2, t3;
+
+#
+# Aggregate function comparation with ALL/ANY/SOME subselect
+#
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+drop table t1,t2;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 3d5a11a26bc..8c4dae92ddc 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/*
+/*
subselect Item
SUBSELECT TODO:
@@ -41,7 +41,7 @@ Item_subselect::Item_subselect():
{
reset();
/*
- item value is NULL if select_subselect not changed this value
+ item value is NULL if select_subselect not changed this value
(i.e. some rows will be found returned)
*/
null_value= 1;
@@ -114,7 +114,7 @@ Item_subselect::~Item_subselect()
}
Item_subselect::trans_res
-Item_subselect::select_transformer(JOIN *join)
+Item_subselect::select_transformer(JOIN *join)
{
DBUG_ENTER("Item_subselect::select_transformer");
DBUG_RETURN(RES_OK);
@@ -153,11 +153,11 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
if (have_to_be_excluded)
engine->exclude();
substitution= 0;
- thd->where= "checking transformed subquery";
+ thd->where= "checking transformed subquery";
if (!(*ref)->fixed)
ret= (*ref)->fix_fields(thd, tables, ref);
- // We can't substitute aggregate functions (like (SELECT (max(i)))
- if ((*ref)->with_sum_func)
+ // We can't substitute aggregate functions like "SELECT (max(i))"
+ if (substype() == SINGLEROW_SUBS && (*ref)->with_sum_func)
{
my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
return 1;
@@ -166,7 +166,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
}
// Is it one field subselect?
if (engine->cols() > max_columns)
- {
+ {
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
return 1;
}
@@ -204,7 +204,7 @@ bool Item_subselect::exec()
return (res);
}
-Item::Type Item_subselect::type() const
+Item::Type Item_subselect::type() const
{
return SUBSELECT_ITEM;
}
@@ -282,7 +282,7 @@ Item_maxmin_subselect::Item_maxmin_subselect(Item_subselect *parent,
*/
used_tables_cache= parent->get_used_tables_cache();
const_item_cache= parent->get_const_item_cache();
-
+
DBUG_VOID_RETURN;
}
@@ -304,7 +304,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
{
if (changed)
return RES_OK;
-
+
SELECT_LEX *select_lex= join->select_lex;
Statement backup;
@@ -319,10 +319,10 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
TODO: solve above problem
*/
!(select_lex->item_list.head()->type() == FIELD_ITEM ||
- select_lex->item_list.head()->type() == REF_ITEM)
+ select_lex->item_list.head()->type() == REF_ITEM)
)
{
-
+
have_to_be_excluded= 1;
if (join->thd->lex->describe)
{
@@ -360,7 +360,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
return RES_REDUCE;
}
return RES_OK;
-
+
err:
if (stmt)
thd->restore_backup_item_arena(stmt, &backup);
@@ -423,7 +423,7 @@ void Item_singlerow_subselect::bring_value()
exec();
}
-double Item_singlerow_subselect::val()
+double Item_singlerow_subselect::val()
{
DBUG_ASSERT(fixed == 1);
if (!exec() && !value->null_value)
@@ -438,7 +438,7 @@ double Item_singlerow_subselect::val()
}
}
-longlong Item_singlerow_subselect::val_int()
+longlong Item_singlerow_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
if (!exec() && !value->null_value)
@@ -453,7 +453,7 @@ longlong Item_singlerow_subselect::val_int()
}
}
-String *Item_singlerow_subselect::val_str (String *str)
+String *Item_singlerow_subselect::val_str (String *str)
{
if (!exec() && !value->null_value)
{
@@ -558,7 +558,7 @@ double Item_exists_subselect::val()
return (double) value;
}
-longlong Item_exists_subselect::val_int()
+longlong Item_exists_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
if (exec())
@@ -595,7 +595,7 @@ double Item_in_subselect::val()
return (double) value;
}
-longlong Item_in_subselect::val_int()
+longlong Item_in_subselect::val_int()
{
DBUG_ASSERT(fixed == 1);
if (exec())
@@ -847,7 +847,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
{
// it is single select without tables => possible optimization
item= func->create(left_expr, item);
- // fix_field of item will be done in time of substituting
+ // fix_field of item will be done in time of substituting
substitution= item;
have_to_be_excluded= 1;
if (thd->lex->describe)
@@ -890,7 +890,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
thd->where= "row IN/ALL/ANY subquery";
if (stmt)
- thd->set_n_backup_item_arena(stmt, &backup);
+ thd->set_n_backup_item_arena(stmt, &backup);
SELECT_LEX *select_lex= join->select_lex;
@@ -931,7 +931,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
List_iterator_fast<Item> li(select_lex->item_list);
for (uint i= 0; i < n; i++)
{
- Item *func= new Item_ref_null_helper(this,
+ Item *func= new Item_ref_null_helper(this,
select_lex->ref_pointer_array+i,
(char *) "<no matter>",
(char *) "<list ref>");
@@ -1113,7 +1113,7 @@ int subselect_single_select_engine::prepare()
(ORDER*) select_lex->order_list.first,
(ORDER*) select_lex->group_list.first,
select_lex->having,
- (ORDER*) 0, select_lex,
+ (ORDER*) 0, select_lex,
select_lex->master_unit()))
return 1;
thd->lex->current_select= save_select;
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 364781de362..6b8b8b0b3a7 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -47,7 +47,7 @@ protected:
/* old engine if engine was changed */
subselect_engine *old_engine;
/* cache of used external tables */
- table_map used_tables_cache;
+ table_map used_tables_cache;
/* allowed number of columns (1 for single value subqueries) */
uint max_columns;
/* work with 'substitution' */
@@ -69,17 +69,17 @@ public:
virtual subs_type substype() { return UNKNOWN_SUBS; }
- /*
+ /*
We need this method, because some compilers do not allow 'this'
pointer in constructor initialization list, but we need pass pointer
to subselect Item class to select_subselect classes constructor.
*/
- virtual void init (st_select_lex *select_lex,
+ virtual void init (st_select_lex *select_lex,
select_subselect *result);
~Item_subselect();
void cleanup();
- virtual void reset()
+ virtual void reset()
{
null_value= 1;
}
@@ -275,7 +275,7 @@ public:
}
virtual ~subselect_engine() {}; // to satisfy compiler
virtual void cleanup()= 0;
-
+
// set_thd should be called before prepare()
void set_thd(THD *thd_arg) { thd= thd_arg; }
THD * get_thd() { return thd; }
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 91df364e531..4305bee42a2 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1706,6 +1706,7 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
unit->reinit_exec_mechanism();
}
}
+ stmt->lex->current_select= &stmt->lex->select_lex;
}