Commit 1a4f499c authored by unknown's avatar unknown

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


mysql-test/r/derived.result:
  explain of hidden select
mysql-test/r/subselect.result:
  explain of hidden select
mysql-test/r/union.result:
  explain of hidden select
  correct error messages on explain
mysql-test/t/subselect.test:
  show eliminated costants in WHERE clause
mysql-test/t/union.test:
  correct error messages on EXPLAIN with union
sql/item.cc:
  fixed name constructing for global ORDER BY items
sql/sql_class.h:
  select ID can be negative (for hidden SELECTs)
  removed unused field
sql/sql_lex.cc:
  new flag of UNION EXPLAIN
sql/sql_lex.h:
  new flag of UNION EXPLAIN
  select ID can be negative (for hidden SELECTs)
sql/sql_select.cc:
  EXPLAIN UNION using same routing which used for execution
  explain for hidden SELECT of UNION
sql/sql_union.cc:
  EXPLAIN UNION using same routing which used for execution
parent cd57fc8b
......@@ -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
2 DERIVED 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;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
2 DERIVED 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);
insert into t2 values(1);
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
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2
4 DERIVED 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
3 UNION t1 ALL NULL NULL NULL NULL 2
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
drop table t1;
CREATE TABLE `t1` (
`N` int(11) unsigned NOT NULL default '0',
......
......@@ -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
1 PRIMARY 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:
Note 1249 Select 2 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
1 PRIMARY 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
-3 UNION RESULT <union3> ALL NULL NULL NULL NULL NULL
Warnings:
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))`
......@@ -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
3 UNION t4 ALL NULL NULL NULL NULL 3 Using where; Using filesort
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL
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)
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
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1
3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 Using where
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
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 #3 was resolved in SELECT #1
......@@ -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
2 SUBQUERY 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:
Note 1003 select high_priority 1 AS `1` from test.t1
drop table t1;
......@@ -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
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
-2 UNION RESULT <union2> ALL NULL NULL NULL NULL NULL
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))))
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
......@@ -1536,11 +1542,14 @@ e
select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
s1
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
1 PRIMARY 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
-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;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
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
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 UNION t2 ALL NULL NULL NULL NULL 4 Using filesort
-1 UNION RESULT <union1> ALL NULL NULL NULL NULL NULL Using filesort
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
(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;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 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;
ERROR 42S22: Unknown column 'xx' in 'field list'
explain select a,b from t1 union select 1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
ERROR 21000: The used SELECT statements have a different number of columns
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
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
ERROR 21000: The used SELECT statements have a different number of columns
explain select a,b from t1 union select 1 limit 0;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 UNION NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
ERROR 21000: The used SELECT statements have a different number of columns
select a,b from t1 into outfile 'skr' union select a,b from t2;
ERROR HY000: Wrong usage of UNION and INTO
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)
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 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:
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);
......@@ -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
2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 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);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1
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;
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 );
......@@ -950,3 +948,8 @@ a
1
drop table t1, t2;
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);
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 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;
#
......
......@@ -39,8 +39,11 @@ explain select a,b from t1 union all select a,b from t2;
--error 1054
explain select xx from t1 union select 1;
--error 1222
explain select a,b from t1 union select 1;
--error 1222
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;
--error 1221
......@@ -515,3 +518,12 @@ SET SQL_SELECT_LIMIT=1;
select a from t1 union select a from t2 order by a;
drop table t1, t2;
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
}
else
{
tmp=(char*) sql_alloc((uint) strlen(table_name)+
(uint) strlen(field_name)+2);
strxmov(tmp,table_name,".",field_name,NullS);
if (table_name[0])
{
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;
}
......
......@@ -768,7 +768,7 @@ public:
uint current_tablenr,tmp_table;
uint server_status,open_options,system_thread;
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 */
enum_tx_isolation session_tx_isolation;
enum_check_fields count_cuted_fields;
......@@ -1147,7 +1147,6 @@ class select_union :public select_result {
TABLE *table;
COPY_INFO info;
TMP_TABLE_PARAM tmp_table_param;
bool not_describe;
select_union(TABLE *table_par);
~select_union();
......
......@@ -1007,6 +1007,7 @@ void st_select_lex_unit::init_query()
fake_select_lex= 0;
cleaned= 0;
item_list.empty();
describe= 0;
}
void st_select_lex::init_query()
......
......@@ -336,6 +336,7 @@ public:
st_select_lex *fake_select_lex;
st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */
bool describe; /* union exec() called for EXPLAIN */
void init_query();
bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result);
......@@ -413,7 +414,7 @@ public:
ulong table_join_options;
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 '*' */
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
/* TRUE when having fix field called in processing of this SELECT */
......
......@@ -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))))
DBUG_RETURN(-1);
......@@ -9132,7 +9132,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
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,
strlen(join->select_lex->type), cs));
for (uint i=0 ; i < 7; i++)
......@@ -9141,6 +9142,49 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (result->send_data(item_list))
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
{
table_map used_tables=0;
......@@ -9150,36 +9194,41 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
TABLE *table=tab->table;
char buff[512],*buff_ptr=buff;
char buff1[512], buff2[512];
char derived_name[64];
char table_name_buffer[64];
String tmp1(buff1,sizeof(buff1),cs);
String tmp2(buff2,sizeof(buff2),cs);
tmp1.length(0);
tmp2.length(0);
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));
if (tab->type == JT_ALL && tab->select && tab->select->quick)
tab->type= JT_RANGE;
/* table */
if (table->derived_select_number)
{
/* 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>",
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
item_list.push_back(new Item_string(table->table_name,
strlen(table->table_name),
cs));
/* type */
item_list.push_back(new Item_string(join_type_str[tab->type],
strlen(join_type_str[tab->type]),
cs));
uint j;
/* possible_keys */
if (!tab->keys.is_clear_all())
{
for (j=0 ; j < table->keys ; j++)
......@@ -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));
else
item_list.push_back(item_null);
/* key key_len ref */
if (tab->ref.key_parts)
{
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,
item_list.push_back(item_null);
item_list.push_back(item_null);
}
/* rows */
item_list.push_back(new Item_int((longlong) (ulonglong)
join->best_positions[i]. records_read,
21));
/* extra */
my_bool key_read=table->key_read;
if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
table->used_keys.is_set(tab->index))
......@@ -9301,32 +9353,53 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
DBUG_ENTER("mysql_explain_union");
int res= 0;
SELECT_LEX *first= unit->first_select();
for (SELECT_LEX *sl= first;
sl;
sl= sl->next_select())
{
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
res= mysql_explain_select(thd, sl,
(((&thd->lex->select_lex)==sl)?
((thd->lex->all_selects_list != sl) ?
primary_key_name : "SIMPLE"):
((sl == first)?
((sl->linkage == DERIVED_TABLE_TYPE) ?
"DERIVED":
((uncacheable & UNCACHEABLE_DEPENDENT) ?
"DEPENDENT SUBQUERY":
(uncacheable?"UNCACHEABLE SUBQUERY":
"SUBQUERY"))):
((uncacheable & UNCACHEABLE_DEPENDENT) ?
"DEPENDENT UNION":
uncacheable?"UNCACHEABLE UNION":
"UNION"))),
result);
if (res)
break;
sl->type= (((&thd->lex->select_lex)==sl)?
((thd->lex->all_selects_list != sl) ?
primary_key_name : "SIMPLE"):
((sl == first)?
((sl->linkage == DERIVED_TABLE_TYPE) ?
"DERIVED":
((uncacheable & UNCACHEABLE_DEPENDENT) ?
"DEPENDENT SUBQUERY":
(uncacheable?"UNCACHEABLE SUBQUERY":
"SUBQUERY"))):
((uncacheable & UNCACHEABLE_DEPENDENT) ?
"DEPENDENT UNION":
uncacheable?"UNCACHEABLE UNION":
"UNION")));
sl->options|= SELECT_DESCRIBE;
}
if (first->next_select())
{
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)
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)
}
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)
{
if (!thd)
......
......@@ -41,7 +41,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result,
***************************************************************************/
select_union::select_union(TABLE *table_par)
:table(table_par), not_describe(0)
:table(table_par)
{
bzero((char*) &info,sizeof(info));
/*
......@@ -114,6 +114,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
select_result *tmp_result;
DBUG_ENTER("st_select_lex_unit::prepare");
describe= test(additional_options & SELECT_DESCRIBE);
/*
result object should be reassigned even if preparing already done for
max/min subquery (ALL/ANY optimization)
......@@ -121,7 +123,26 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
result= sel_result;
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);
}
prepared= 1;
res= 0;
......@@ -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)))
goto err;
union_result->not_describe= 1;
union_result->tmp_table_param.init();
if (describe)
tmp_result= sel_result;
}
else
{
......@@ -269,11 +291,11 @@ int st_select_lex_unit::exec()
ulonglong add_rows=0;
DBUG_ENTER("st_select_lex_unit::exec");
if (executed && !uncacheable)
if (executed && !uncacheable && !describe)
DBUG_RETURN(0);
executed= 1;
if (uncacheable || !item || !item->assigned())
if (uncacheable || !item || !item->assigned() || describe)
{
if (optimized && item && item->assigned())
{
......@@ -292,7 +314,7 @@ int st_select_lex_unit::exec()
res= sl->join->reinit();
else
{
if (sl != global_parameters)
if (sl != global_parameters && !describe)
{
offset_limit_cnt= sl->offset_limit;
select_limit_cnt= sl->select_limit+sl->offset_limit;
......@@ -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
whole query
*/
if (sl->order_list.first)
if (sl->order_list.first || describe)
select_limit_cnt= HA_POS_ERROR;
else
select_limit_cnt= sl->select_limit+sl->offset_limit;
......@@ -373,7 +395,7 @@ int st_select_lex_unit::exec()
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;
offset_limit_cnt= global_parameters->offset_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