diff options
-rw-r--r-- | mysql-test/r/subselect.result | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/sql_derived.cc | 10 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 107 | ||||
-rw-r--r-- | sql/sql_select.cc | 4 |
6 files changed, 37 insertions, 90 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index b1bf134fdde..5674bf3c473 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -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 (select * from t2 where a>1) as tt; 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 +3 DERIVED t2 ALL NULL NULL NULL NULL 2 where used 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); a diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c61621bf91d..a6771c9754d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -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, 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, - bool tables_is_opened); +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item_result_field ***copy_func, Field **from_field, bool group,bool modify_item); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 1335618b90d..93627409d27 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -28,8 +28,7 @@ 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, - bool tables_is_opened) +int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) { /* 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) { res= mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor, 0); + cursor); 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++)) 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)) { @@ -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->table=table; 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->derived=(SELECT_LEX *)0; // just in case ... } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5327801bf9c..0865e6da05f 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -959,6 +959,7 @@ void st_select_lex::init_query() table_list.next= (byte**) &table_list.first; item_list.empty(); join= 0; + olap= UNSPECIFIED_OLAP_TYPE; } void st_select_lex::init_select() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 57325ef19cf..4288773b00b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1328,74 +1328,24 @@ mysql_execute_command(THD *thd) #endif } - select_result *explain_result= 0; /* TODO: make derived tables processing 'inside' SELECT processing. TODO: solve problem with depended derived tables in subselects */ - if (lex->sql_command == SQLCOM_SELECT && - 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) +if (lex->derived_tables) { for (TABLE_LIST *cursor= tables; cursor; cursor= cursor->next) if (cursor->derived && (res=mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor, 0))) + cursor))) { if (res < 0) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); DBUG_VOID_RETURN; } - } + } if ((lex->select_lex.next_select_in_list() && lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && @@ -1435,19 +1385,18 @@ mysql_execute_command(THD *thd) { if (lex->describe) { - if (!explain_result) - if (!(explain_result= new select_send())) - { - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_VOID_RETURN; - } - else - thd->send_explain_fields(explain_result); + if (!(result= new select_send())) + { + send_error(thd, ER_OUT_OF_RESOURCES); + DBUG_VOID_RETURN; + } + else + thd->send_explain_fields(result); 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; thd->lock= (MYSQL_LOCK *)0; - explain_result->send_eof(); + result->send_eof(); thd->lock= save_lock; } else @@ -2901,26 +2850,24 @@ void mysql_init_query(THD *thd) { DBUG_ENTER("mysql_init_query"); - thd->lex.unit.init_query(); - thd->lex.unit.init_select(); - thd->lex.select_lex.init_query(); - thd->lex.unit.slave= &thd->lex.select_lex; - thd->lex.unit.global_parameters= &thd->lex.select_lex; //Global limit & order - thd->lex.select_lex.master= &thd->lex.unit; - thd->lex.select_lex.prev= &thd->lex.unit.slave; - thd->select_number= thd->lex.select_lex.select_number= 1; - thd->lex.value_list.empty(); + LEX *lex=&thd->lex; + lex->unit.init_query(); + lex->unit.init_select(); + lex->select_lex.init_query(); + lex->value_list.empty(); + lex->param_list.empty(); + lex->unit.global_parameters= lex->unit.slave= lex->current_select= &lex->select_lex; + lex->select_lex.master= &lex->unit; + 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->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->last_insert_id_used= thd->query_start_used= thd->insert_id_used=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->lex.param_list.empty(); DBUG_VOID_RETURN; } @@ -2932,7 +2879,6 @@ mysql_init_select(LEX *lex) select_lex->init_select(); select_lex->master_unit()->select_limit= select_lex->select_limit= lex->thd->variables.select_limit; - select_lex->olap= UNSPECIFIED_OLAP_TYPE; lex->exchange= 0; lex->result= 0; lex->proc_list.first= 0; @@ -3016,14 +2962,13 @@ mysql_parse(THD *thd, char *inBuf, uint length) mysql_init_query(thd); thd->query_length = length; - thd->lex.derived_tables= false; if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) { LEX *lex=lex_start(thd, (uchar*) inBuf, length); if (!yyparse() && ! thd->fatal_error) { if (mqh_used && thd->user_connect && - check_mqh(thd, thd->lex.sql_command)) + check_mqh(thd, lex->sql_command)) { thd->net.error = 0; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b9162daadaa..674caed0cd0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7458,8 +7458,10 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ((sl->next_select_in_list())?"PRIMARY": "SIMPLE"): ((sl == first)? + ((sl->linkage == DERIVED_TABLE_TYPE) ? + "DERIVED": ((sl->dependent)?"DEPENDENT SUBSELECT": - "SUBSELECT"): + "SUBSELECT")): ((sl->dependent)?"DEPENDENT UNION": "UNION"))), result); |