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:
parent
1684cfbc28
commit
fb2cd68b5d
@ -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;
|
||||||
|
@ -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;
|
||||||
|
29
sql/item.cc
29
sql/item.cc
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user