fixed subselect explain bug
mysql-test/r/subselect.result: test for subselect explain bug mysql-test/t/subselect.test: test for subselect explain bug
This commit is contained in:
parent
5dcaaf4e04
commit
103330a3c0
@ -54,9 +54,9 @@ explain 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);
|
union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 where used
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 where used
|
||||||
|
2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 Using filesort
|
||||||
3 UNION t4 ALL NULL NULL NULL NULL 3 where used; Using filesort
|
3 UNION t4 ALL NULL NULL NULL NULL 3 where used; Using filesort
|
||||||
4 SUBSELECT t2 ALL NULL NULL NULL NULL 2
|
4 SUBSELECT t2 ALL NULL NULL NULL NULL 2
|
||||||
2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 Using filesort
|
|
||||||
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
|
||||||
@ -163,9 +163,7 @@ UNIQUE KEY `email` (`email`)
|
|||||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
|
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
|
||||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
|
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
|
||||||
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
|
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
|
||||||
EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT
|
EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce');
|
||||||
pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT
|
|
||||||
pseudo FROM inscrit WHERE pseudo='joce');
|
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY inscrit const PRIMARY PRIMARY 35 const 1
|
1 PRIMARY inscrit const PRIMARY PRIMARY 35 const 1
|
||||||
4 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1
|
4 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1
|
||||||
@ -183,3 +181,21 @@ joce
|
|||||||
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
|
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
|
||||||
Subselect returns more than 1 record
|
Subselect returns more than 1 record
|
||||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
||||||
|
drop table if exists searchconthardwarefr3;
|
||||||
|
CREATE TABLE `searchconthardwarefr3` (
|
||||||
|
`topic` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`date` date NOT NULL default '0000-00-00',
|
||||||
|
`pseudo` varchar(35) character set latin1 NOT NULL default '',
|
||||||
|
PRIMARY KEY (`pseudo`,`date`,`topic`),
|
||||||
|
KEY `topic` (`topic`)
|
||||||
|
) TYPE=MyISAM ROW_FORMAT=DYNAMIC;
|
||||||
|
INSERT INTO searchconthardwarefr3 (topic,date,pseudo) VALUES
|
||||||
|
('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
|
||||||
|
EXPLAIN SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE searchconthardwarefr3 index NULL PRIMARY 41 NULL 2 where used; Using index
|
||||||
|
EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY No tables used
|
||||||
|
2 SUBSELECT searchconthardwarefr3 index NULL PRIMARY 41 NULL 2 where used; Using index
|
||||||
|
drop table searchconthardwarefr3;
|
||||||
|
@ -83,9 +83,7 @@ CREATE TABLE `inscrit` (
|
|||||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
|
INSERT INTO inscrit (pseudo,email) VALUES ('joce','test');
|
||||||
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
|
INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1');
|
||||||
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
|
INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1');
|
||||||
EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT
|
EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce');
|
||||||
pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT
|
|
||||||
pseudo FROM inscrit WHERE pseudo='joce');
|
|
||||||
-- error 1239
|
-- error 1239
|
||||||
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo,email FROM
|
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo,email FROM
|
||||||
inscrit WHERE pseudo='joce');
|
inscrit WHERE pseudo='joce');
|
||||||
@ -97,3 +95,17 @@ SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo
|
|||||||
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
|
SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%');
|
||||||
|
|
||||||
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
|
||||||
|
|
||||||
|
drop table if exists searchconthardwarefr3;
|
||||||
|
CREATE TABLE `searchconthardwarefr3` (
|
||||||
|
`topic` mediumint(8) unsigned NOT NULL default '0',
|
||||||
|
`date` date NOT NULL default '0000-00-00',
|
||||||
|
`pseudo` varchar(35) character set latin1 NOT NULL default '',
|
||||||
|
PRIMARY KEY (`pseudo`,`date`,`topic`),
|
||||||
|
KEY `topic` (`topic`)
|
||||||
|
) TYPE=MyISAM ROW_FORMAT=DYNAMIC;
|
||||||
|
INSERT INTO searchconthardwarefr3 (topic,date,pseudo) VALUES
|
||||||
|
('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
|
||||||
|
EXPLAIN SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03';
|
||||||
|
EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03');
|
||||||
|
drop table searchconthardwarefr3;
|
@ -392,6 +392,8 @@ int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
|
|||||||
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex,
|
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex,
|
||||||
bool fake_select_lex);
|
bool fake_select_lex);
|
||||||
void fix_tables_pointers(SELECT_LEX *select_lex);
|
void fix_tables_pointers(SELECT_LEX *select_lex);
|
||||||
|
int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
|
||||||
|
select_result *result);
|
||||||
int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
|
int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
|
||||||
select_result *result);
|
select_result *result);
|
||||||
int mysql_union(THD *thd, LEX *lex,select_result *result);
|
int mysql_union(THD *thd, LEX *lex,select_result *result);
|
||||||
|
@ -955,6 +955,7 @@ void st_select_lex::init_query()
|
|||||||
table_list.first= 0;
|
table_list.first= 0;
|
||||||
table_list.next= (byte**) &table_list.first;
|
table_list.next= (byte**) &table_list.first;
|
||||||
item_list.empty();
|
item_list.empty();
|
||||||
|
join= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_select_lex::init_select()
|
void st_select_lex::init_select()
|
||||||
@ -973,7 +974,6 @@ void st_select_lex::init_select()
|
|||||||
ftfunc_list= &ftfunc_list_alloc;
|
ftfunc_list= &ftfunc_list_alloc;
|
||||||
linkage= UNSPECIFIED_TYPE;
|
linkage= UNSPECIFIED_TYPE;
|
||||||
depended= having_fix_field= 0;
|
depended= having_fix_field= 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1484,24 +1484,7 @@ mysql_execute_command(THD *thd)
|
|||||||
else
|
else
|
||||||
thd->send_explain_fields(explain_result);
|
thd->send_explain_fields(explain_result);
|
||||||
fix_tables_pointers(select_lex);
|
fix_tables_pointers(select_lex);
|
||||||
for ( SELECT_LEX *sl= select_lex;
|
res= mysql_explain_union(thd, &thd->lex.unit, explain_result);
|
||||||
sl && res == 0;
|
|
||||||
sl= sl->next_select_in_list())
|
|
||||||
{
|
|
||||||
SELECT_LEX *first= sl->master_unit()->first_select();
|
|
||||||
res= mysql_explain_select(thd, sl,
|
|
||||||
((select_lex==sl)?
|
|
||||||
((sl->next_select_in_list())?"PRIMARY":
|
|
||||||
"SIMPLE"):
|
|
||||||
((sl == first)?
|
|
||||||
((sl->depended)?"DEPENDENT SUBSELECT":
|
|
||||||
"SUBSELECT"):
|
|
||||||
((sl->depended)?"DEPENDENT UNION":
|
|
||||||
"UNION"))),
|
|
||||||
explain_result);
|
|
||||||
}
|
|
||||||
if (res > 0)
|
|
||||||
res= -res; // mysql_explain_select do not report error
|
|
||||||
MYSQL_LOCK *save_lock= thd->lock;
|
MYSQL_LOCK *save_lock= thd->lock;
|
||||||
thd->lock= (MYSQL_LOCK *)0;
|
thd->lock= (MYSQL_LOCK *)0;
|
||||||
explain_result->send_eof();
|
explain_result->send_eof();
|
||||||
|
@ -1018,9 +1018,25 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
|
|||||||
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex,
|
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex,
|
||||||
bool fake_select_lex)
|
bool fake_select_lex)
|
||||||
{
|
{
|
||||||
JOIN *join = new JOIN(thd, fields, select_options, result);
|
|
||||||
|
|
||||||
DBUG_ENTER("mysql_select");
|
DBUG_ENTER("mysql_select");
|
||||||
|
|
||||||
|
bool free_join= 1;
|
||||||
|
JOIN *join;
|
||||||
|
if (!fake_select_lex && select_lex->join != 0)
|
||||||
|
{
|
||||||
|
//here is EXPLAIN of subselect or derived table
|
||||||
|
join= select_lex->join;
|
||||||
|
join->result= result;
|
||||||
|
if (!join->procedure && result->prepare(join->fields_list, unit))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
join->select_options= select_options;
|
||||||
|
free_join= 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
join= new JOIN(thd, fields, select_options, result);
|
||||||
thd->proc_info="init";
|
thd->proc_info="init";
|
||||||
thd->used_tables=0; // Updated by setup_fields
|
thd->used_tables=0; // Updated by setup_fields
|
||||||
|
|
||||||
@ -1029,19 +1045,24 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
|
|||||||
{
|
{
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
switch (join->optimize()) {
|
}
|
||||||
|
|
||||||
|
switch (join->optimize())
|
||||||
|
{
|
||||||
case 1:
|
case 1:
|
||||||
DBUG_RETURN(join->error);
|
DBUG_RETURN(join->error);
|
||||||
case -1:
|
case -1:
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (join->global_optimize())
|
if (free_join && join->global_optimize())
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
join->exec();
|
join->exec();
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
if (free_join)
|
||||||
|
{
|
||||||
thd->limit_found_rows = join->send_records;
|
thd->limit_found_rows = join->send_records;
|
||||||
thd->examined_row_count = join->examined_rows;
|
thd->examined_row_count = join->examined_rows;
|
||||||
thd->proc_info="end";
|
thd->proc_info="end";
|
||||||
@ -1049,6 +1070,9 @@ err:
|
|||||||
delete join;
|
delete join;
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
Create JOIN_TABS, make a guess about the table types,
|
Create JOIN_TABS, make a guess about the table types,
|
||||||
@ -7366,8 +7390,42 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||||||
result->send_error(0,NullS);
|
result->send_error(0,NullS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
|
||||||
|
unit;
|
||||||
|
unit= unit->next_unit())
|
||||||
|
{
|
||||||
|
if (mysql_explain_union(thd, unit, result))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
|
||||||
|
{
|
||||||
|
int res= 0;
|
||||||
|
SELECT_LEX *first= unit->first_select();
|
||||||
|
for (SELECT_LEX *sl= first;
|
||||||
|
sl;
|
||||||
|
sl= sl->next_select())
|
||||||
|
{
|
||||||
|
res= mysql_explain_select(thd, sl,
|
||||||
|
(((&thd->lex.select_lex)==sl)?
|
||||||
|
((sl->next_select_in_list())?"PRIMARY":
|
||||||
|
"SIMPLE"):
|
||||||
|
((sl == first)?
|
||||||
|
((sl->depended)?"DEPENDENT SUBSELECT":
|
||||||
|
"SUBSELECT"):
|
||||||
|
((sl->depended)?"DEPENDENT UNION":
|
||||||
|
"UNION"))),
|
||||||
|
result);
|
||||||
|
if (res)
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (res > 0)
|
||||||
|
res= -res; // mysql_explain_select do not report error
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
|
int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
|
||||||
select_result *result)
|
select_result *result)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user