Commit 3aae50e8 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

EXPLAIN UNION using same routing which used for execution which allow return...

EXPLAIN UNION using same routing which used for execution which allow return correct bug messages (Bug #3639)
EXPLAIN of hidden SELECT of UNION
parent ec33d794
...@@ -94,11 +94,13 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -94,11 +94,13 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
2 DERIVED t1 ALL NULL NULL NULL NULL 4 2 DERIVED t1 ALL NULL NULL NULL NULL 4
3 UNION t1 ALL NULL NULL NULL NULL 4 3 UNION t1 ALL NULL NULL NULL NULL 4
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
explain select * from (select * from t1 union all select * from t1) a; explain select * from (select * from t1 union all select * from t1) 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 <derived2> ALL NULL NULL NULL NULL 8 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
2 DERIVED t1 ALL NULL NULL NULL NULL 4 2 DERIVED t1 ALL NULL NULL NULL NULL 4
3 UNION t1 ALL NULL NULL NULL NULL 4 3 UNION t1 ALL NULL NULL NULL NULL 4
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
CREATE TABLE t2 (a int not null); CREATE TABLE t2 (a int not null);
insert into t2 values(1); insert into t2 values(1);
select * from (select * from t1 where t1.a=(select a from t2 where t2.a=t1.a)) a; select * from (select * from t1 where t1.a=(select a from t2 where t2.a=t1.a)) a;
...@@ -246,8 +248,10 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -246,8 +248,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2
4 DERIVED t1 ALL NULL NULL NULL NULL 2 4 DERIVED t1 ALL NULL NULL NULL NULL 2
5 UNION t1 ALL NULL NULL NULL NULL 2 5 UNION t1 ALL NULL NULL NULL NULL 2
-4 UNION RESULT <union4> ALL NULL NULL NULL NULL NULL
2 DERIVED t1 ALL NULL NULL NULL NULL 2 2 DERIVED t1 ALL NULL NULL NULL NULL 2
3 UNION t1 ALL NULL NULL NULL NULL 2 3 UNION t1 ALL NULL NULL NULL NULL 2
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`N` int(11) unsigned NOT NULL default '0', `N` int(11) unsigned NOT NULL default '0',
......
...@@ -16,6 +16,7 @@ explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2); ...@@ -16,6 +16,7 @@ explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
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 NULL NULL NULL NULL NULL NULL NULL No tables used 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1249 Select 2 was reduced during optimisation Note 1249 Select 2 was reduced during optimisation
Note 1249 Select 4 was reduced during optimisation Note 1249 Select 4 was reduced during optimisation
...@@ -28,6 +29,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -28,6 +29,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used 4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-3 UNION RESULT <union3> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1249 Select 2 was reduced during optimisation Note 1249 Select 2 was reduced during optimisation
Note 1003 select high_priority (select 0 AS `0` union select 0 AS `0`) AS `(SELECT (SELECT 0 UNION SELECT 0))` Note 1003 select high_priority (select 0 AS `0` union select 0 AS `0`) AS `(SELECT (SELECT 0 UNION SELECT 0))`
...@@ -182,6 +184,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -182,6 +184,7 @@ id select_type table type possible_keys key key_len ref rows Extra
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using filesort 2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using filesort
3 UNION t4 ALL NULL NULL NULL NULL 3 Using where; Using filesort 3 UNION t4 ALL NULL NULL NULL NULL 3 Using where; Using filesort
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select high_priority test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.b = (select test.t3.a AS `a` from test.t3 order by test.t3.a desc limit 1))) union (select test.t4.a AS `a`,test.t4.b AS `b` from test.t4 where (test.t4.b = (select (max(test.t2.a) * 4) AS `max(t2.a)*4` from test.t2)) order by test.t4.a) Note 1003 (select high_priority test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.b = (select test.t3.a AS `a` from test.t3 order by test.t3.a desc limit 1))) union (select test.t4.a AS `a`,test.t4.b AS `b` from test.t4 where (test.t4.b = (select (max(test.t2.a) * 4) AS `max(t2.a)*4` from test.t2)) order by test.t4.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;
...@@ -306,6 +309,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -306,6 +309,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1
3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 Using where 3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 Using where
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1276 Field or reference 't2.a' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 't2.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 't2.a' of SELECT #3 was resolved in SELECT #1 Note 1276 Field or reference 't2.a' of SELECT #3 was resolved in SELECT #1
...@@ -413,6 +417,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -413,6 +417,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL topic 3 NULL 2 Using index 1 PRIMARY t1 index NULL topic 3 NULL 2 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select high_priority 1 AS `1` from test.t1 Note 1003 select high_priority 1 AS `1` from test.t1
drop table t1; drop table t1;
...@@ -727,6 +732,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -727,6 +732,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index NULL id 5 NULL 2 Using where; Using index 1 PRIMARY t2 index NULL id 5 NULL 2 Using where; Using index
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used 3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select high_priority test.t2.id AS `id` from test.t2 where <in_optimizer>(test.t2.id,<exists>(select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(1)) union select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(3)))) Note 1003 select high_priority test.t2.id AS `id` from test.t2 where <in_optimizer>(test.t2.id,<exists>(select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(1)) union select 1 AS `Not_used` having (<cache>(test.t2.id) = <null_helper>(3))))
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3); SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
...@@ -1536,11 +1542,14 @@ e ...@@ -1536,11 +1542,14 @@ e
select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
s1 s1
e e
explain select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
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 t1 system NULL NULL NULL NULL 1 1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY t1 system NULL NULL NULL NULL 1 2 SUBQUERY t1 system NULL NULL NULL NULL 1
3 UNION t1 system NULL NULL NULL NULL 1 3 UNION t1 system NULL NULL NULL NULL 1
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
Warnings:
Note 1003 select high_priority test.t1.s1 AS `s1` from test.t1
drop table t1; drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1; CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874'); INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
......
...@@ -86,6 +86,7 @@ explain extended (select a,b from t1 limit 2) union all (select a,b from t2 ord ...@@ -86,6 +86,7 @@ explain extended (select a,b from t1 limit 2) union all (select a,b from t2 ord
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 t1 ALL NULL NULL NULL NULL 4 1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 UNION t2 ALL NULL NULL NULL NULL 4 Using filesort 2 UNION t2 ALL NULL NULL NULL NULL 4 Using filesort
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL Using filesort
Warnings: Warnings:
Note 1003 (select high_priority test.t1.a AS `a`,test.t1.b AS `b` from test.t1 limit 2) union all (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 order by test.t2.a limit 1) order by b desc Note 1003 (select high_priority test.t1.a AS `a`,test.t1.b AS `b` from test.t1 limit 2) union all (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 order by test.t2.a limit 1) order by b desc
(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2; (select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2;
...@@ -106,21 +107,15 @@ explain select a,b from t1 union all select a,b from t2; ...@@ -106,21 +107,15 @@ explain select a,b from t1 union all select a,b from t2;
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 t1 ALL NULL NULL NULL NULL 4 1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 UNION t2 ALL NULL NULL NULL NULL 4 2 UNION t2 ALL NULL NULL NULL NULL 4
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL
explain select xx from t1 union select 1; explain select xx from t1 union select 1;
ERROR 42S22: Unknown column 'xx' in 'field list' ERROR 42S22: Unknown column 'xx' in 'field list'
explain select a,b from t1 union select 1; explain select a,b from t1 union select 1;
id select_type table type possible_keys key key_len ref rows Extra ERROR 21000: The used SELECT statements have a different number of columns
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
explain select 1 union select a,b from t1 union select 1; explain select 1 union select a,b from t1 union select 1;
id select_type table type possible_keys key key_len ref rows Extra ERROR 21000: The used SELECT statements have a different number of columns
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
2 UNION t1 ALL NULL NULL NULL NULL 4
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
explain select a,b from t1 union select 1 limit 0; explain select a,b from t1 union select 1 limit 0;
id select_type table type possible_keys key key_len ref rows Extra ERROR 21000: The used SELECT statements have a different number of columns
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 UNION NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
select a,b from t1 into outfile 'skr' union select a,b from t2; select a,b from t1 into outfile 'skr' union select a,b from t2;
ERROR HY000: Wrong usage of UNION and INTO ERROR HY000: Wrong usage of UNION and INTO
select a,b from t1 order by a union select a,b from t2; select a,b from t1 order by a union select a,b from t2;
...@@ -475,6 +470,7 @@ explain extended (select * from t1 where a=1) union (select * from t2 where a=1) ...@@ -475,6 +470,7 @@ explain extended (select * from t1 where a=1) union (select * from t2 where a=1)
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 t1 const PRIMARY PRIMARY 4 const 1 1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1
2 UNION t2 const PRIMARY PRIMARY 4 const 1 2 UNION t2 const PRIMARY PRIMARY 4 const 1
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select high_priority test.t1.a AS `a`,test.t1.b AS `b` from test.t1 where (test.t1.a = 1)) union (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.a = 1)) Note 1003 (select high_priority test.t1.a AS `a`,test.t1.b AS `b` from test.t1 where (test.t1.a = 1)) union (select test.t2.a AS `a`,test.t2.b AS `b` from test.t2 where (test.t2.a = 1))
(select * from t1 where a=5) union (select * from t2 where a=1); (select * from t1 where a=5) union (select * from t2 where a=1);
...@@ -497,10 +493,12 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -497,10 +493,12 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index 2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index
2 UNION t2 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index 2 UNION t2 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL
explain (select * from t1 where a=1) union (select * from t1 where b=1); explain (select * from t1 where a=1) union (select * from t1 where b=1);
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 t1 const PRIMARY PRIMARY 4 const 1 1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1
2 UNION t1 ref b b 5 const 1 Using where 2 UNION t1 ref b b 5 const 1 Using where
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL
drop table t1,t2; drop table t1,t2;
create table t1 ( id int not null auto_increment, primary key (id) ,user_name text ); create table t1 ( id int not null auto_increment, primary key (id) ,user_name text );
create table t2 ( id int not null auto_increment, primary key (id) ,group_name text ); create table t2 ( id int not null auto_increment, primary key (id) ,group_name text );
...@@ -950,3 +948,8 @@ a ...@@ -950,3 +948,8 @@ a
1 1
drop table t1, t2; drop table t1, t2;
set sql_select_limit=default; set sql_select_limit=default;
CREATE TABLE t1 (i int(11) default NULL,c char(1) default NULL,KEY i (i));
CREATE TABLE t2 (i int(11) default NULL,c char(1) default NULL,KEY i (i));
explain (select * from t1) union (select * from t2) order by not_existing_column;
ERROR 42S22: Unknown column 'not_existing_column' in 'order clause'
drop table t1, t2;
...@@ -974,7 +974,7 @@ create table t1 (s1 char); ...@@ -974,7 +974,7 @@ create table t1 (s1 char);
insert into t1 values ('e'); insert into t1 values ('e');
select * from t1 where 'f' > any (select s1 from t1); select * from t1 where 'f' > any (select s1 from t1);
select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
explain select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1); explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
drop table t1; drop table t1;
# #
......
...@@ -39,8 +39,11 @@ explain select a,b from t1 union all select a,b from t2; ...@@ -39,8 +39,11 @@ explain select a,b from t1 union all select a,b from t2;
--error 1054 --error 1054
explain select xx from t1 union select 1; explain select xx from t1 union select 1;
--error 1222
explain select a,b from t1 union select 1; explain select a,b from t1 union select 1;
--error 1222
explain select 1 union select a,b from t1 union select 1; explain select 1 union select a,b from t1 union select 1;
--error 1222
explain select a,b from t1 union select 1 limit 0; explain select a,b from t1 union select 1 limit 0;
--error 1221 --error 1221
...@@ -515,3 +518,12 @@ SET SQL_SELECT_LIMIT=1; ...@@ -515,3 +518,12 @@ SET SQL_SELECT_LIMIT=1;
select a from t1 union select a from t2 order by a; select a from t1 union select a from t2 order by a;
drop table t1, t2; drop table t1, t2;
set sql_select_limit=default; set sql_select_limit=default;
#
# nonexisting column in global ORDER BY
#
CREATE TABLE t1 (i int(11) default NULL,c char(1) default NULL,KEY i (i));
CREATE TABLE t2 (i int(11) default NULL,c char(1) default NULL,KEY i (i));
--error 1054
explain (select * from t1) union (select * from t2) order by not_existing_column;
drop table t1, t2;
...@@ -369,9 +369,14 @@ const char *Item_ident::full_name() const ...@@ -369,9 +369,14 @@ const char *Item_ident::full_name() const
} }
else else
{ {
tmp=(char*) sql_alloc((uint) strlen(table_name)+ if (table_name[0])
(uint) strlen(field_name)+2); {
strxmov(tmp,table_name,".",field_name,NullS); tmp= (char*) sql_alloc((uint) strlen(table_name) +
(uint) strlen(field_name) + 2);
strxmov(tmp, table_name, ".", field_name, NullS);
}
else
tmp= (char*) field_name;
} }
return tmp; return tmp;
} }
......
...@@ -768,7 +768,7 @@ public: ...@@ -768,7 +768,7 @@ public:
uint current_tablenr,tmp_table; uint current_tablenr,tmp_table;
uint server_status,open_options,system_thread; uint server_status,open_options,system_thread;
uint32 db_length; uint32 db_length;
uint select_number; //number of select (used for EXPLAIN) int select_number; //number of select (used for EXPLAIN)
/* variables.transaction_isolation is reset to this after each commit */ /* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation session_tx_isolation; enum_tx_isolation session_tx_isolation;
enum_check_fields count_cuted_fields; enum_check_fields count_cuted_fields;
...@@ -1147,7 +1147,6 @@ class select_union :public select_result { ...@@ -1147,7 +1147,6 @@ class select_union :public select_result {
TABLE *table; TABLE *table;
COPY_INFO info; COPY_INFO info;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
bool not_describe;
select_union(TABLE *table_par); select_union(TABLE *table_par);
~select_union(); ~select_union();
......
...@@ -1007,6 +1007,7 @@ void st_select_lex_unit::init_query() ...@@ -1007,6 +1007,7 @@ void st_select_lex_unit::init_query()
fake_select_lex= 0; fake_select_lex= 0;
cleaned= 0; cleaned= 0;
item_list.empty(); item_list.empty();
describe= 0;
} }
void st_select_lex::init_query() void st_select_lex::init_query()
......
...@@ -336,6 +336,7 @@ public: ...@@ -336,6 +336,7 @@ public:
st_select_lex *fake_select_lex; st_select_lex *fake_select_lex;
st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */ st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */
bool describe; /* union exec() called for EXPLAIN */
void init_query(); void init_query();
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
...@@ -413,7 +414,7 @@ public: ...@@ -413,7 +414,7 @@ public:
ulong table_join_options; ulong table_join_options;
uint in_sum_expr; uint in_sum_expr;
uint select_number; /* number of select (used for EXPLAIN) */ int select_number; /* number of select (used for EXPLAIN) */
uint with_wild; /* item list contain '*' */ uint with_wild; /* item list contain '*' */
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
/* TRUE when having fix field called in processing of this SELECT */ /* TRUE when having fix field called in processing of this SELECT */
......
...@@ -991,7 +991,7 @@ JOIN::optimize() ...@@ -991,7 +991,7 @@ JOIN::optimize()
} }
} }
if (select_lex->master_unit()->uncacheable) if (select_lex->master_unit()->uncacheable || thd->lex->describe)
{ {
if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -9132,7 +9132,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -9132,7 +9132,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (message) if (message)
{ {
item_list.push_back(new Item_int((int32) join->select_lex->select_number)); item_list.push_back(new Item_int((longlong)
join->select_lex->select_number));
item_list.push_back(new Item_string(join->select_lex->type, item_list.push_back(new Item_string(join->select_lex->type,
strlen(join->select_lex->type), cs)); strlen(join->select_lex->type), cs));
for (uint i=0 ; i < 7; i++) for (uint i=0 ; i < 7; i++)
...@@ -9141,6 +9142,49 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -9141,6 +9142,49 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (result->send_data(item_list)) if (result->send_data(item_list))
join->error= 1; join->error= 1;
} }
else if (join->select_lex == join->unit->fake_select_lex)
{
/*
Here is guessing about fake_select_lex to avoid union SELECT
execution to get accurate information
*/
char table_name_buffer[64];
item_list.empty();
/* id */
item_list.push_back(new Item_int((int32)
join->select_lex->select_number));
/* select_type */
item_list.push_back(new Item_string(join->select_lex->type,
strlen(join->select_lex->type),
cs));
/* table */
int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
"<union%d>",
-join->select_lex->select_number);
item_list.push_back(new Item_string(table_name_buffer, len, cs));
item_list.push_back(new Item_string(join_type_str[JT_ALL],
strlen(join_type_str[JT_ALL]),
cs));
/* possible_keys */
item_list.push_back(item_null);
/* key*/
item_list.push_back(item_null);
/* key_len */
item_list.push_back(item_null);
/* ref */
item_list.push_back(item_null);
/* rows */
item_list.push_back(item_null);
/* extra */
if (join->unit->global_parameters->order_list.first)
item_list.push_back(new Item_string("Using filesort",
14, cs));
else
item_list.push_back(new Item_string("", 0, cs));
if (result->send_data(item_list))
join->error= 1;
}
else else
{ {
table_map used_tables=0; table_map used_tables=0;
...@@ -9150,36 +9194,41 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -9150,36 +9194,41 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
TABLE *table=tab->table; TABLE *table=tab->table;
char buff[512],*buff_ptr=buff; char buff[512],*buff_ptr=buff;
char buff1[512], buff2[512]; char buff1[512], buff2[512];
char derived_name[64]; char table_name_buffer[64];
String tmp1(buff1,sizeof(buff1),cs); String tmp1(buff1,sizeof(buff1),cs);
String tmp2(buff2,sizeof(buff2),cs); String tmp2(buff2,sizeof(buff2),cs);
tmp1.length(0); tmp1.length(0);
tmp2.length(0); tmp2.length(0);
item_list.empty(); item_list.empty();
/* id */
item_list.push_back(new Item_int((int32) item_list.push_back(new Item_int((int32)
join->select_lex->select_number)); join->select_lex->select_number));
/* select_type */
item_list.push_back(new Item_string(join->select_lex->type, item_list.push_back(new Item_string(join->select_lex->type,
strlen(join->select_lex->type), strlen(join->select_lex->type),
cs)); cs));
if (tab->type == JT_ALL && tab->select && tab->select->quick) if (tab->type == JT_ALL && tab->select && tab->select->quick)
tab->type= JT_RANGE; tab->type= JT_RANGE;
/* table */
if (table->derived_select_number) if (table->derived_select_number)
{ {
/* Derived table name generation */ /* Derived table name generation */
int len= my_snprintf(derived_name, sizeof(derived_name)-1, int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
"<derived%u>", "<derived%u>",
table->derived_select_number); table->derived_select_number);
item_list.push_back(new Item_string(derived_name, len, cs)); item_list.push_back(new Item_string(table_name_buffer, len, cs));
} }
else else
item_list.push_back(new Item_string(table->table_name, item_list.push_back(new Item_string(table->table_name,
strlen(table->table_name), strlen(table->table_name),
cs)); cs));
/* type */
item_list.push_back(new Item_string(join_type_str[tab->type], item_list.push_back(new Item_string(join_type_str[tab->type],
strlen(join_type_str[tab->type]), strlen(join_type_str[tab->type]),
cs)); cs));
uint j; uint j;
/* possible_keys */
if (!tab->keys.is_clear_all()) if (!tab->keys.is_clear_all())
{ {
for (j=0 ; j < table->keys ; j++) for (j=0 ; j < table->keys ; j++)
...@@ -9196,6 +9245,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -9196,6 +9245,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs)); item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
else else
item_list.push_back(item_null); item_list.push_back(item_null);
/* key key_len ref */
if (tab->ref.key_parts) if (tab->ref.key_parts)
{ {
KEY *key_info=table->key_info+ tab->ref.key; KEY *key_info=table->key_info+ tab->ref.key;
...@@ -9234,9 +9284,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -9234,9 +9284,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
item_list.push_back(item_null); item_list.push_back(item_null);
item_list.push_back(item_null); item_list.push_back(item_null);
} }
/* rows */
item_list.push_back(new Item_int((longlong) (ulonglong) item_list.push_back(new Item_int((longlong) (ulonglong)
join->best_positions[i]. records_read, join->best_positions[i]. records_read,
21)); 21));
/* extra */
my_bool key_read=table->key_read; my_bool key_read=table->key_read;
if ((tab->type == JT_NEXT || tab->type == JT_CONST) && if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
table->used_keys.is_set(tab->index)) table->used_keys.is_set(tab->index))
...@@ -9301,32 +9353,53 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ...@@ -9301,32 +9353,53 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
DBUG_ENTER("mysql_explain_union"); DBUG_ENTER("mysql_explain_union");
int res= 0; int res= 0;
SELECT_LEX *first= unit->first_select(); SELECT_LEX *first= unit->first_select();
for (SELECT_LEX *sl= first; for (SELECT_LEX *sl= first;
sl; sl;
sl= sl->next_select()) sl= sl->next_select())
{ {
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN); uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
sl->type= (((&thd->lex->select_lex)==sl)?
res= mysql_explain_select(thd, sl, ((thd->lex->all_selects_list != sl) ?
(((&thd->lex->select_lex)==sl)? primary_key_name : "SIMPLE"):
((thd->lex->all_selects_list != sl) ? ((sl == first)?
primary_key_name : "SIMPLE"): ((sl->linkage == DERIVED_TABLE_TYPE) ?
((sl == first)? "DERIVED":
((sl->linkage == DERIVED_TABLE_TYPE) ? ((uncacheable & UNCACHEABLE_DEPENDENT) ?
"DERIVED": "DEPENDENT SUBQUERY":
((uncacheable & UNCACHEABLE_DEPENDENT) ? (uncacheable?"UNCACHEABLE SUBQUERY":
"DEPENDENT SUBQUERY": "SUBQUERY"))):
(uncacheable?"UNCACHEABLE SUBQUERY": ((uncacheable & UNCACHEABLE_DEPENDENT) ?
"SUBQUERY"))): "DEPENDENT UNION":
((uncacheable & UNCACHEABLE_DEPENDENT) ? uncacheable?"UNCACHEABLE UNION":
"DEPENDENT UNION": "UNION")));
uncacheable?"UNCACHEABLE UNION": sl->options|= SELECT_DESCRIBE;
"UNION"))), }
result); if (first->next_select())
if (res) {
break; unit->fake_select_lex->select_number= -first->select_number;
unit->fake_select_lex->type= "UNION RESULT";
unit->fake_select_lex->options|= SELECT_DESCRIBE;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
res= unit->exec();
res|= unit->cleanup();
}
else
{
thd->lex->current_select= first;
res= mysql_select(thd, &first->ref_pointer_array,
(TABLE_LIST*) first->table_list.first,
first->with_wild, first->item_list,
first->where,
first->order_list.elements +
first->group_list.elements,
(ORDER*) first->order_list.first,
(ORDER*) first->group_list.first,
first->having,
(ORDER*) thd->lex->proc_list.first,
first->options | thd->options | SELECT_DESCRIBE,
result, unit, first);
} }
if (res > 0 || thd->net.report_error) if (res > 0 || thd->net.report_error)
res= -1; // mysql_explain_select do not report error res= -1; // mysql_explain_select do not report error
...@@ -9334,30 +9407,6 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ...@@ -9334,30 +9407,6 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
} }
int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
select_result *result)
{
DBUG_ENTER("mysql_explain_select");
DBUG_PRINT("info", ("Select 0x%lx, type %s", (ulong)select_lex, type))
select_lex->type= type;
thd->lex->current_select= select_lex;
SELECT_LEX_UNIT *unit= select_lex->master_unit();
int res= mysql_select(thd, &select_lex->ref_pointer_array,
(TABLE_LIST*) select_lex->table_list.first,
select_lex->with_wild, select_lex->item_list,
select_lex->where,
select_lex->order_list.elements +
select_lex->group_list.elements,
(ORDER*) select_lex->order_list.first,
(ORDER*) select_lex->group_list.first,
select_lex->having,
(ORDER*) thd->lex->proc_list.first,
select_lex->options | thd->options | SELECT_DESCRIBE,
result, unit, select_lex);
DBUG_RETURN(res);
}
void st_select_lex::print(THD *thd, String *str) void st_select_lex::print(THD *thd, String *str)
{ {
if (!thd) if (!thd)
......
...@@ -41,7 +41,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result, ...@@ -41,7 +41,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result,
***************************************************************************/ ***************************************************************************/
select_union::select_union(TABLE *table_par) select_union::select_union(TABLE *table_par)
:table(table_par), not_describe(0) :table(table_par)
{ {
bzero((char*) &info,sizeof(info)); bzero((char*) &info,sizeof(info));
/* /*
...@@ -114,6 +114,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -114,6 +114,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
select_result *tmp_result; select_result *tmp_result;
DBUG_ENTER("st_select_lex_unit::prepare"); DBUG_ENTER("st_select_lex_unit::prepare");
describe= test(additional_options & SELECT_DESCRIBE);
/* /*
result object should be reassigned even if preparing already done for result object should be reassigned even if preparing already done for
max/min subquery (ALL/ANY optimization) max/min subquery (ALL/ANY optimization)
...@@ -121,7 +123,26 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -121,7 +123,26 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
result= sel_result; result= sel_result;
if (prepared) if (prepared)
{
if (describe)
{
/* fast reinit for EXPLAIN */
for (sl= first_select_in_union(); sl; sl= sl->next_select())
{
sl->join->result= result;
select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0;
if (!sl->join->procedure &&
result->prepare(sl->join->fields_list, this))
{
DBUG_RETURN(1);
}
sl->join->select_options|= SELECT_DESCRIBE;
sl->join->reinit();
}
}
DBUG_RETURN(0); DBUG_RETURN(0);
}
prepared= 1; prepared= 1;
res= 0; res= 0;
...@@ -134,8 +155,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -134,8 +155,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
{ {
if (!(tmp_result= union_result= new select_union(0))) if (!(tmp_result= union_result= new select_union(0)))
goto err; goto err;
union_result->not_describe= 1;
union_result->tmp_table_param.init(); union_result->tmp_table_param.init();
if (describe)
tmp_result= sel_result;
} }
else else
{ {
...@@ -269,11 +291,11 @@ int st_select_lex_unit::exec() ...@@ -269,11 +291,11 @@ int st_select_lex_unit::exec()
ulonglong add_rows=0; ulonglong add_rows=0;
DBUG_ENTER("st_select_lex_unit::exec"); DBUG_ENTER("st_select_lex_unit::exec");
if (executed && !uncacheable) if (executed && !uncacheable && !describe)
DBUG_RETURN(0); DBUG_RETURN(0);
executed= 1; executed= 1;
if (uncacheable || !item || !item->assigned()) if (uncacheable || !item || !item->assigned() || describe)
{ {
if (optimized && item && item->assigned()) if (optimized && item && item->assigned())
{ {
...@@ -292,7 +314,7 @@ int st_select_lex_unit::exec() ...@@ -292,7 +314,7 @@ int st_select_lex_unit::exec()
res= sl->join->reinit(); res= sl->join->reinit();
else else
{ {
if (sl != global_parameters) if (sl != global_parameters && !describe)
{ {
offset_limit_cnt= sl->offset_limit; offset_limit_cnt= sl->offset_limit;
select_limit_cnt= sl->select_limit+sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit;
...@@ -304,7 +326,7 @@ int st_select_lex_unit::exec() ...@@ -304,7 +326,7 @@ int st_select_lex_unit::exec()
We can't use LIMIT at this stage if we are using ORDER BY for the We can't use LIMIT at this stage if we are using ORDER BY for the
whole query whole query
*/ */
if (sl->order_list.first) if (sl->order_list.first || describe)
select_limit_cnt= HA_POS_ERROR; select_limit_cnt= HA_POS_ERROR;
else else
select_limit_cnt= sl->select_limit+sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit;
...@@ -373,7 +395,7 @@ int st_select_lex_unit::exec() ...@@ -373,7 +395,7 @@ int st_select_lex_unit::exec()
if (!thd->is_fatal_error) // Check if EOM if (!thd->is_fatal_error) // Check if EOM
{ {
ulong options_tmp= thd->options; ulong options_tmp= thd->options | fake_select_lex->options;
thd->lex->current_select= fake_select_lex; thd->lex->current_select= fake_select_lex;
offset_limit_cnt= global_parameters->offset_limit; offset_limit_cnt= global_parameters->offset_limit;
select_limit_cnt= global_parameters->select_limit + select_limit_cnt= global_parameters->select_limit +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment