new subselect tests

LIMIT fixed
AVG & STD with subselect fixed
join_free fixed to be depended queries compatible
sort_default removed from SELECT_LEX
This commit is contained in:
bell@sanja.is.com.ua 2002-06-01 23:35:36 +03:00
parent 1684cfbc28
commit fb2cd68b5d
9 changed files with 75 additions and 29 deletions

View File

@ -1,3 +1,6 @@
select (select 2);
(select 2)
2
drop table if exists t1,t2,t3,t4; drop table if exists t1,t2,t3,t4;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
@ -26,18 +29,42 @@ select * from t2 where t2.a=(select a from t1);
a b a b
2 7 2 7
insert into t3 values (6),(7),(3); insert into t3 values (6),(7),(3);
select * from t2 where t2.b=(select a from t3 order by 1 limit 1); select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
a b a b
1 7 1 7
2 7 2 7
select * from t2 where t2.b=(select a from t3 order by 1 limit 1) select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 order by a limit 2) limit 3; union (select * from t4 order by a limit 2) limit 3;
a b a b
1 7 1 7
2 7 2 7
3 8 3 8
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
a b
1 7
2 7
3 8
4 8
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
7 2 7 2
select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt;
(select t3.a from t3 where a<8 order by 1 desc limit 1) a
7 2
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
a
2
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
a
2
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
a
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
8 7.5000
8 6.0000
9 5.5000
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;

View File

@ -1,5 +1,5 @@
#select (select 2); select (select 2);
drop table if exists t1,t2,t3,t4; drop table if exists t1,t2,t3,t4;
create table t1 (a int); create table t1 (a int);
create table t2 (a int, b int); create table t2 (a int, b int);
@ -17,7 +17,13 @@ insert into t3 values (6),(7),(3);
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1); select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 order by a limit 2) limit 3; union (select * from t4 order by a limit 2) limit 3;
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt; (select * from t2 where a>1) as tt;
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;

View File

@ -330,23 +330,32 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
mention of table name, but if we join tables in one list it will mention of table name, but if we join tables in one list it will
cause error ER_NON_UNIQ_ERROR in find_field_in_tables. cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
*/ */
SELECT_LEX *last;
for (SELECT_LEX *sl= thd->lex.select->outer_select(); for (SELECT_LEX *sl= thd->lex.select->outer_select();
sl && !tmp; sl && !tmp;
sl= sl->outer_select()) sl= sl->outer_select())
tmp=find_field_in_tables(thd, this, tmp=find_field_in_tables(thd, this,
(TABLE_LIST*)sl->table_list.first); (TABLE_LIST*)(last= sl)->table_list.first);
if (!tmp) if (!tmp)
return 1; return 1;
else else
if( !thd->lex.select->depended ) /*
{ Mark all selects from resolved to 1 before select where was
thd->lex.select->depended= 1; //Select is depended of outer select(s) found table as depended (of select where was found table)
//Tables will be reopened many times */
for (TABLE_LIST *tbl= (TABLE_LIST*)thd->lex.select->table_list.first; for (SELECT_LEX *s= thd->lex.select;
tbl; s &&s != last;
tbl= tbl->next) s= s->outer_select())
tbl->shared= 1; if( !s->depended )
} {
s->depended= 1; //Select is depended of outer select
//Tables will be reopened many times
for (TABLE_LIST *tbl=
(TABLE_LIST*)s->table_list.first;
tbl;
tbl= tbl->next)
tbl->shared= 1;
}
} }
set_field(tmp); set_field(tmp);
} }

View File

@ -23,6 +23,7 @@ SUBSELECT TODO:
- remove double 'having' & 'having_list' from JOIN - remove double 'having' & 'having_list' from JOIN
(sql_select.h/sql_select.cc) (sql_select.h/sql_select.cc)
- subselect in HAVING clause
- add subselect union select (sql_union.cc) - add subselect union select (sql_union.cc)
*/ */
@ -43,7 +44,7 @@ Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex):
SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX_UNIT *unit= select_lex->master_unit();
unit->offset_limit_cnt= unit->global_parameters->offset_limit; unit->offset_limit_cnt= unit->global_parameters->offset_limit;
unit->select_limit_cnt= unit->global_parameters->select_limit+ unit->select_limit_cnt= unit->global_parameters->select_limit+
select_lex->offset_limit; unit->global_parameters ->offset_limit;
if (unit->select_limit_cnt < unit->global_parameters->select_limit) if (unit->select_limit_cnt < unit->global_parameters->select_limit)
unit->select_limit_cnt= HA_POS_ERROR; // no limit unit->select_limit_cnt= HA_POS_ERROR; // no limit
if (unit->select_limit_cnt == HA_POS_ERROR) if (unit->select_limit_cnt == HA_POS_ERROR)
@ -148,9 +149,6 @@ int Item_subselect::exec()
join->thd->lex.select= select_lex; join->thd->lex.select= select_lex;
join->exec(); join->exec();
join->thd->lex.select= save_select; join->thd->lex.select= save_select;
//if (!executed)
//No rows returned => value is null (returned as inited)
// executed= 1;
return join->error; return join->error;
} }
return 0; return 0;

View File

@ -790,11 +790,17 @@ bool select_subselect::send_data(List<Item> &items)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (unit->offset_limit_cnt) if (unit->offset_limit_cnt)
{ // using limit offset,count { // Using limit offset,count
unit->offset_limit_cnt--; unit->offset_limit_cnt--;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
Item *val_item= (Item *)item->select_lex->item_list.head(); List_iterator_fast<Item> li(items);
Item *val_item= li++; // Only one (single value subselect)
/*
Following val() call have to be first, because function AVG() & STD()
calculate value on it & determinate "is it NULL?".
*/
item->real_value= val_item->val();
if ((item->null_value= val_item->is_null())) if ((item->null_value= val_item->is_null()))
{ {
item->assign_null(); item->assign_null();
@ -804,7 +810,6 @@ bool select_subselect::send_data(List<Item> &items)
item->binary= val_item->binary; item->binary= val_item->binary;
val_item->val_str(&item->str_value); val_item->val_str(&item->str_value);
item->int_value= val_item->val_int(); item->int_value= val_item->val_int();
item->real_value= val_item->val();
item->res_type= val_item->result_type(); item->res_type= val_item->result_type();
} }
item->executed= 1; item->executed= 1;

View File

@ -194,7 +194,6 @@ protected:
public: public:
ulong options; ulong options;
enum sub_select_type linkage; enum sub_select_type linkage;
//uint sort_default;
SQL_LIST order_list; /* ORDER clause */ SQL_LIST order_list; /* ORDER clause */
ha_rows select_limit, offset_limit; /* LIMIT clause parameters */ ha_rows select_limit, offset_limit; /* LIMIT clause parameters */
void init_query(); void init_query();

View File

@ -2690,12 +2690,12 @@ mysql_init_query(THD *thd)
void void
mysql_init_select(LEX *lex) mysql_init_select(LEX *lex)
{ {
SELECT_LEX *select_lex = lex->select; SELECT_LEX *select_lex= lex->select;
select_lex->init_select(); select_lex->init_select();
select_lex->select_limit=lex->thd->default_select_limit; select_lex->master_unit()->select_limit= select_lex->select_limit=
select_lex->offset_limit=0; lex->thd->default_select_limit;
lex->exchange = 0; lex->exchange= 0;
lex->proc_list.first=0; lex->proc_list.first= 0;
} }
bool bool

View File

@ -607,9 +607,10 @@ JOIN::reinit()
unit->select_limit_cnt= HA_POS_ERROR; // no limit unit->select_limit_cnt= HA_POS_ERROR; // no limit
if (unit->select_limit_cnt == HA_POS_ERROR) if (unit->select_limit_cnt == HA_POS_ERROR)
select_lex->options&= ~OPTION_FOUND_ROWS; select_lex->options&= ~OPTION_FOUND_ROWS;
if (setup_tables(tables_list)) if (setup_tables(tables_list))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -2830,7 +2831,9 @@ join_free(JOIN *join)
} }
end_read_record(&tab->read_record); end_read_record(&tab->read_record);
} }
join->table=0; //TODO: is enough join_free at the end of mysql_select?
if (!join->select_lex->depended)
join->table=0;
} }
// We are not using tables anymore // We are not using tables anymore
// Unlock all tables. We may be in an INSERT .... SELECT statement. // Unlock all tables. We may be in an INSERT .... SELECT statement.

View File

@ -2325,7 +2325,6 @@ order_clause:
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sql_command == SQLCOM_MULTI_UPDATE) if (lex->sql_command == SQLCOM_MULTI_UPDATE)
YYABORT; YYABORT;
/*lex->select->sort_default=1;*/
} order_list } order_list
order_list: order_list: