diff options
author | unknown <bell@sanja.is.com.ua> | 2004-10-27 21:17:31 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-10-27 21:17:31 +0300 |
commit | a94c7639da634502edaae1d28c09dea924159032 (patch) | |
tree | 8613fb623c030f24afa43b30b38a0839da9a2f38 | |
parent | 55833fb49bf8570ee11d4b85b143a9a3975733fa (diff) | |
parent | 464da8f13a69d7ce51e1c130475e1a8c4cab59a5 (diff) | |
download | mariadb-git-a94c7639da634502edaae1d28c09dea924159032.tar.gz |
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-ps-4.1
-rw-r--r-- | mysql-test/r/subselect.result | 15 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 5 | ||||
-rw-r--r-- | sql/item_subselect.cc | 91 | ||||
-rw-r--r-- | sql/item_subselect.h | 4 |
4 files changed, 91 insertions, 24 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 04c5f685f58..32d482f5a32 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -55,7 +55,7 @@ SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; 1 1 SELECT (SELECT 1), a; -ERROR 42S22: Unknown column 'a' in 'checking transformed subquery' +ERROR 42S22: Unknown column 'a' in 'field list' SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1; a 1 @@ -999,7 +999,9 @@ drop table t1, t2; CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1; INSERT INTO t1 VALUES (1); UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); -ERROR HY000: Invalid use of group function +select * from t1; +i +1 drop table t1; CREATE TABLE t1 (a int(1)); EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1; @@ -1084,7 +1086,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` bigint(20) NOT NULL default '0', - `(SELECT a)` bigint(20) default NULL + `(SELECT a)` bigint(20) NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a; @@ -1102,7 +1104,7 @@ a SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` bigint(20) default NULL + `a` bigint(20) NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 (a int); @@ -1186,11 +1188,12 @@ PRIMARY KEY (`i`) ) ENGINE=MyISAM CHARSET=latin1; INSERT INTO t1 VALUES (1); UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i)); -ERROR HY000: Invalid use of group function UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); -ERROR HY000: Invalid use of group function UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t); ERROR 42S02: Unknown table 't' in field list +select * from t1; +i +1 drop table t1; CREATE TABLE t1 ( id int(11) default NULL diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 5e3aa4064e4..e0f6fcbf515 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -543,8 +543,8 @@ drop table t1, t2; CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1; INSERT INTO t1 VALUES (1); --- error 1111 UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); +select * from t1; drop table t1; #test of uncacheable subqueries @@ -689,12 +689,11 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM CHARSET=latin1; INSERT INTO t1 VALUES (1); --- error 1111 UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i)); --- error 1111 UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); -- error 1109 UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t); +select * from t1; drop table t1; # diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a869e2d24fb..401d4dee20f 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -164,12 +164,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) 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 (substype() == SINGLEROW_SUBS && (*ref)->with_sum_func) - { - my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0)); - return 1; - } + thd->where= save_where; return ret; } // Is it one field subselect? @@ -322,6 +317,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join) if (!select_lex->master_unit()->first_select()->next_select() && !select_lex->table_list.elements && select_lex->item_list.elements == 1 && + !select_lex->item_list.head()->with_sum_func && /* We cant change name of Item_field or Item_ref, because it will prevent it's correct resolving, but we should save name of @@ -330,7 +326,13 @@ 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) && + /* + switch off this optimisation for prepare statement, + because we do not rollback this changes + TODO: make rollback for it, or special name resolving mode in 5.0. + */ + !arena->is_stmt_prepare() ) { @@ -352,9 +354,6 @@ Item_singlerow_subselect::select_transformer(JOIN *join) if (join->conds || join->having) { Item *cond; - if (arena->is_stmt_prepare()) - thd->set_n_backup_item_arena(arena, &backup); - if (!join->having) cond= join->conds; else if (!join->conds) @@ -365,16 +364,12 @@ Item_singlerow_subselect::select_transformer(JOIN *join) if (!(substitution= new Item_func_if(cond, substitution, new Item_null()))) goto err; - if (arena->is_stmt_prepare()) - thd->restore_backup_item_arena(arena, &backup); - } + } return RES_REDUCE; } return RES_OK; err: - if (arena->is_stmt_prepare()) - thd->restore_backup_item_arena(arena, &backup); return RES_ERROR; } @@ -401,6 +396,13 @@ void Item_singlerow_subselect::fix_length_and_dec() engine->fix_length_and_dec(row); value= *row; } + /* + If there are not tables in subquery then ability to have NULL value + depends on SELECT list (if single row subquery have tables then it + always can be NULL if there are not records fetched). + */ + if (engine->no_tables()) + maybe_null= engine->may_be_null(); } uint Item_singlerow_subselect::cols() @@ -644,6 +646,7 @@ Item_subselect::trans_res Item_in_subselect::single_value_transformer(JOIN *join, Comp_creator *func) { + const char *save_where= thd->where; DBUG_ENTER("Item_in_subselect::single_value_transformer"); if (changed) @@ -899,6 +902,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ok: if (arena->is_stmt_prepare()) thd->restore_backup_item_arena(arena, &backup); + thd->where= save_where; DBUG_RETURN(RES_OK); err: @@ -911,6 +915,7 @@ err: Item_subselect::trans_res Item_in_subselect::row_value_transformer(JOIN *join) { + const char *save_where= thd->where; DBUG_ENTER("Item_in_subselect::row_value_transformer"); if (changed) @@ -1003,6 +1008,7 @@ Item_in_subselect::row_value_transformer(JOIN *join) } if (arena->is_stmt_prepare()) thd->restore_backup_item_arena(arena, &backup); + thd->where= save_where; DBUG_RETURN(RES_OK); err: @@ -1562,3 +1568,58 @@ int subselect_uniquesubquery_engine::change_item(Item_subselect *si, DBUG_ASSERT(0); return -1; } + + +/* + Report about presence of tables in subquery + + SINOPSYS + subselect_single_select_engine::no_tables() + + RETURN + TRUE there are not tables used in subquery + FALSE there are some tables in subquery +*/ +bool subselect_single_select_engine::no_tables() +{ + return(select_lex->table_list.elements == 0); +} + + +/* + Report about presence of tables in subquery + + SINOPSYS + subselect_union_engine::no_tables() + + RETURN + TRUE there are not tables used in subquery + FALSE there are some tables in subquery +*/ +bool subselect_union_engine::no_tables() +{ + for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) + { + if (sl->table_list.elements) + return FALSE; + } + return TRUE; +} + + +/* + Report about presence of tables in subquery + + SINOPSYS + subselect_uniquesubquery_engine::no_tables() + + RETURN + TRUE there are not tables used in subquery + FALSE there are some tables in subquery +*/ + +bool subselect_uniquesubquery_engine::no_tables() +{ + /* returning value is correct, but this method should never be called */ + return 0; +} diff --git a/sql/item_subselect.h b/sql/item_subselect.h index f570d89f28f..764c41f33b4 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -291,6 +291,7 @@ public: static table_map calc_const_tables(TABLE_LIST *); virtual void print(String *str)= 0; virtual int change_item(Item_subselect *si, select_subselect *result)= 0; + virtual bool no_tables()= 0; }; @@ -315,6 +316,7 @@ public: table_map upper_select_const_tables(); void print (String *str); int change_item(Item_subselect *si, select_subselect *result); + bool no_tables(); }; @@ -335,6 +337,7 @@ public: table_map upper_select_const_tables(); void print (String *str); int change_item(Item_subselect *si, select_subselect *result); + bool no_tables(); }; @@ -364,6 +367,7 @@ public: table_map upper_select_const_tables() { return 0; } void print (String *str); int change_item(Item_subselect *si, select_subselect *result); + bool no_tables(); }; |