Some code optimisations related to EXPLAIN of derived tables and the
resulting code cleanup in our main loop.
This commit is contained in:
parent
826aa607ff
commit
f980950bb3
@ -71,8 +71,8 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
|||||||
explain select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
explain 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;
|
||||||
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
|
||||||
3 DERIVED t2 ALL NULL NULL NULL NULL 2 where used
|
|
||||||
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
|
||||||
|
3 DERIVED t2 ALL NULL NULL NULL NULL 2 where used
|
||||||
2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 where used; Using filesort
|
2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 where used; Using filesort
|
||||||
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) order by 1 desc limit 1);
|
||||||
a
|
a
|
||||||
|
@ -399,8 +399,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit,
|
|||||||
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);
|
||||||
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t,
|
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t);
|
||||||
bool tables_is_opened);
|
|
||||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||||
Item_result_field ***copy_func, Field **from_field,
|
Item_result_field ***copy_func, Field **from_field,
|
||||||
bool group,bool modify_item);
|
bool group,bool modify_item);
|
||||||
|
@ -28,8 +28,7 @@
|
|||||||
static const char *any_db="*any*"; // Special symbol for check_access
|
static const char *any_db="*any*"; // Special symbol for check_access
|
||||||
|
|
||||||
|
|
||||||
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t,
|
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
|
||||||
bool tables_is_opened)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
TODO: make derived tables with union inside (now only 1 SELECT may be
|
TODO: make derived tables with union inside (now only 1 SELECT may be
|
||||||
@ -58,7 +57,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t,
|
|||||||
if (cursor->derived)
|
if (cursor->derived)
|
||||||
{
|
{
|
||||||
res= mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived,
|
res= mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived,
|
||||||
cursor, 0);
|
cursor);
|
||||||
if (res) DBUG_RETURN(res);
|
if (res) DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,7 +67,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t,
|
|||||||
while ((item= it++))
|
while ((item= it++))
|
||||||
item_list.push_back(item);
|
item_list.push_back(item);
|
||||||
|
|
||||||
if (tables_is_opened || !(res=open_and_lock_tables(thd,tables)))
|
if (!(res=open_and_lock_tables(thd,tables)))
|
||||||
{
|
{
|
||||||
if (setup_fields(thd,tables,item_list,0,0,1))
|
if (setup_fields(thd,tables,item_list,0,0,1))
|
||||||
{
|
{
|
||||||
@ -112,7 +111,8 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t,
|
|||||||
t->real_name=table->real_name;
|
t->real_name=table->real_name;
|
||||||
t->table=table;
|
t->table=table;
|
||||||
table->derived_select_number= sl->select_number;
|
table->derived_select_number= sl->select_number;
|
||||||
sl->exclude();
|
if (!lex->describe)
|
||||||
|
sl->exclude();
|
||||||
t->db= (tables && tables->db && tables->db[0]) ? t->db : thd->db;
|
t->db= (tables && tables->db && tables->db[0]) ? t->db : thd->db;
|
||||||
t->derived=(SELECT_LEX *)0; // just in case ...
|
t->derived=(SELECT_LEX *)0; // just in case ...
|
||||||
}
|
}
|
||||||
|
@ -959,6 +959,7 @@ void st_select_lex::init_query()
|
|||||||
table_list.next= (byte**) &table_list.first;
|
table_list.next= (byte**) &table_list.first;
|
||||||
item_list.empty();
|
item_list.empty();
|
||||||
join= 0;
|
join= 0;
|
||||||
|
olap= UNSPECIFIED_OLAP_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_select_lex::init_select()
|
void st_select_lex::init_select()
|
||||||
|
105
sql/sql_parse.cc
105
sql/sql_parse.cc
@ -1328,68 +1328,18 @@ mysql_execute_command(THD *thd)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
select_result *explain_result= 0;
|
|
||||||
/*
|
/*
|
||||||
TODO: make derived tables processing 'inside' SELECT processing.
|
TODO: make derived tables processing 'inside' SELECT processing.
|
||||||
TODO: solve problem with depended derived tables in subselects
|
TODO: solve problem with depended derived tables in subselects
|
||||||
*/
|
*/
|
||||||
if (lex->sql_command == SQLCOM_SELECT &&
|
if (lex->derived_tables)
|
||||||
lex->describe && lex->derived_tables)
|
|
||||||
{
|
|
||||||
if (!(explain_result= new select_send()))
|
|
||||||
{
|
|
||||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
//check rights
|
|
||||||
for (cursor= tables;
|
|
||||||
cursor;
|
|
||||||
cursor= cursor->next)
|
|
||||||
if (cursor->derived)
|
|
||||||
{
|
|
||||||
TABLE_LIST *tables=
|
|
||||||
(TABLE_LIST *)((SELECT_LEX_UNIT *)
|
|
||||||
cursor->derived)->first_select()->table_list.first;
|
|
||||||
int res;
|
|
||||||
if (tables)
|
|
||||||
res= check_table_access(thd,SELECT_ACL, tables);
|
|
||||||
else
|
|
||||||
res= check_access(thd, SELECT_ACL, any_db);
|
|
||||||
if (res)
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
thd->send_explain_fields(explain_result);
|
|
||||||
// EXPLAIN derived tables
|
|
||||||
for (cursor= tables;
|
|
||||||
cursor;
|
|
||||||
cursor= cursor->next)
|
|
||||||
if (cursor->derived)
|
|
||||||
{
|
|
||||||
SELECT_LEX *select_lex= ((SELECT_LEX_UNIT *)
|
|
||||||
cursor->derived)->first_select();
|
|
||||||
if (!open_and_lock_tables(thd,
|
|
||||||
(TABLE_LIST*) select_lex->table_list.first))
|
|
||||||
{
|
|
||||||
mysql_explain_select(thd, select_lex,
|
|
||||||
"DERIVED", explain_result);
|
|
||||||
// execute derived table SELECT to provide table for other SELECTs
|
|
||||||
if (mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived,
|
|
||||||
cursor, 1))
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (lex->derived_tables)
|
|
||||||
{
|
{
|
||||||
for (TABLE_LIST *cursor= tables;
|
for (TABLE_LIST *cursor= tables;
|
||||||
cursor;
|
cursor;
|
||||||
cursor= cursor->next)
|
cursor= cursor->next)
|
||||||
if (cursor->derived && (res=mysql_derived(thd, lex,
|
if (cursor->derived && (res=mysql_derived(thd, lex,
|
||||||
(SELECT_LEX_UNIT *)cursor->derived,
|
(SELECT_LEX_UNIT *)cursor->derived,
|
||||||
cursor, 0)))
|
cursor)))
|
||||||
{
|
{
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||||
@ -1435,19 +1385,18 @@ mysql_execute_command(THD *thd)
|
|||||||
{
|
{
|
||||||
if (lex->describe)
|
if (lex->describe)
|
||||||
{
|
{
|
||||||
if (!explain_result)
|
if (!(result= new select_send()))
|
||||||
if (!(explain_result= new select_send()))
|
{
|
||||||
{
|
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
DBUG_VOID_RETURN;
|
||||||
DBUG_VOID_RETURN;
|
}
|
||||||
}
|
else
|
||||||
else
|
thd->send_explain_fields(result);
|
||||||
thd->send_explain_fields(explain_result);
|
|
||||||
fix_tables_pointers(select_lex);
|
fix_tables_pointers(select_lex);
|
||||||
res= mysql_explain_union(thd, &thd->lex.unit, explain_result);
|
res= mysql_explain_union(thd, &thd->lex.unit, result);
|
||||||
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();
|
result->send_eof();
|
||||||
thd->lock= save_lock;
|
thd->lock= save_lock;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2901,26 +2850,24 @@ void
|
|||||||
mysql_init_query(THD *thd)
|
mysql_init_query(THD *thd)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mysql_init_query");
|
DBUG_ENTER("mysql_init_query");
|
||||||
thd->lex.unit.init_query();
|
LEX *lex=&thd->lex;
|
||||||
thd->lex.unit.init_select();
|
lex->unit.init_query();
|
||||||
thd->lex.select_lex.init_query();
|
lex->unit.init_select();
|
||||||
thd->lex.unit.slave= &thd->lex.select_lex;
|
lex->select_lex.init_query();
|
||||||
thd->lex.unit.global_parameters= &thd->lex.select_lex; //Global limit & order
|
lex->value_list.empty();
|
||||||
thd->lex.select_lex.master= &thd->lex.unit;
|
lex->param_list.empty();
|
||||||
thd->lex.select_lex.prev= &thd->lex.unit.slave;
|
lex->unit.global_parameters= lex->unit.slave= lex->current_select= &lex->select_lex;
|
||||||
thd->select_number= thd->lex.select_lex.select_number= 1;
|
lex->select_lex.master= &lex->unit;
|
||||||
thd->lex.value_list.empty();
|
lex->select_lex.prev= &lex->unit.slave;
|
||||||
|
lex->olap=lex->describe=0;
|
||||||
|
lex->derived_tables= false;
|
||||||
|
thd->select_number= lex->select_lex.select_number= 1;
|
||||||
thd->free_list= 0;
|
thd->free_list= 0;
|
||||||
thd->lex.current_select= &thd->lex.select_lex;
|
|
||||||
thd->lex.olap=thd->lex.describe=0;
|
|
||||||
thd->lex.select_lex.olap= UNSPECIFIED_OLAP_TYPE;
|
|
||||||
thd->fatal_error= 0; // Safety
|
|
||||||
thd->total_warn_count=0; // Warnings for this query
|
thd->total_warn_count=0; // Warnings for this query
|
||||||
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
|
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
|
||||||
thd->sent_row_count= thd->examined_row_count= 0;
|
thd->sent_row_count= thd->examined_row_count= 0;
|
||||||
thd->rand_used=0;
|
thd->fatal_error= thd->rand_used=0;
|
||||||
thd->safe_to_cache_query= 1;
|
thd->safe_to_cache_query= 1;
|
||||||
thd->lex.param_list.empty();
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2932,7 +2879,6 @@ mysql_init_select(LEX *lex)
|
|||||||
select_lex->init_select();
|
select_lex->init_select();
|
||||||
select_lex->master_unit()->select_limit= select_lex->select_limit=
|
select_lex->master_unit()->select_limit= select_lex->select_limit=
|
||||||
lex->thd->variables.select_limit;
|
lex->thd->variables.select_limit;
|
||||||
select_lex->olap= UNSPECIFIED_OLAP_TYPE;
|
|
||||||
lex->exchange= 0;
|
lex->exchange= 0;
|
||||||
lex->result= 0;
|
lex->result= 0;
|
||||||
lex->proc_list.first= 0;
|
lex->proc_list.first= 0;
|
||||||
@ -3016,14 +2962,13 @@ mysql_parse(THD *thd, char *inBuf, uint length)
|
|||||||
|
|
||||||
mysql_init_query(thd);
|
mysql_init_query(thd);
|
||||||
thd->query_length = length;
|
thd->query_length = length;
|
||||||
thd->lex.derived_tables= false;
|
|
||||||
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
|
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
|
||||||
{
|
{
|
||||||
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
|
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
|
||||||
if (!yyparse() && ! thd->fatal_error)
|
if (!yyparse() && ! thd->fatal_error)
|
||||||
{
|
{
|
||||||
if (mqh_used && thd->user_connect &&
|
if (mqh_used && thd->user_connect &&
|
||||||
check_mqh(thd, thd->lex.sql_command))
|
check_mqh(thd, lex->sql_command))
|
||||||
{
|
{
|
||||||
thd->net.error = 0;
|
thd->net.error = 0;
|
||||||
}
|
}
|
||||||
|
@ -7458,8 +7458,10 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
|
|||||||
((sl->next_select_in_list())?"PRIMARY":
|
((sl->next_select_in_list())?"PRIMARY":
|
||||||
"SIMPLE"):
|
"SIMPLE"):
|
||||||
((sl == first)?
|
((sl == first)?
|
||||||
|
((sl->linkage == DERIVED_TABLE_TYPE) ?
|
||||||
|
"DERIVED":
|
||||||
((sl->dependent)?"DEPENDENT SUBSELECT":
|
((sl->dependent)?"DEPENDENT SUBSELECT":
|
||||||
"SUBSELECT"):
|
"SUBSELECT")):
|
||||||
((sl->dependent)?"DEPENDENT UNION":
|
((sl->dependent)?"DEPENDENT UNION":
|
||||||
"UNION"))),
|
"UNION"))),
|
||||||
result);
|
result);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user