diff options
-rw-r--r-- | mysql-test/r/derived.result | 4 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 11 | ||||
-rw-r--r-- | mysql-test/r/union.result | 23 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 2 | ||||
-rw-r--r-- | mysql-test/t/union.test | 12 | ||||
-rw-r--r-- | sql/item.cc | 11 | ||||
-rw-r--r-- | sql/sql_class.h | 3 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 145 | ||||
-rw-r--r-- | sql/sql_union.cc | 34 |
11 files changed, 177 insertions, 72 deletions
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index 81e2cd03d1a..cdbca9aa2aa 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -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', diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index d512ecdf34d..22438967b57 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -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 (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 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 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 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'); diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index c85b59be38c..4655f92c7d7 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -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 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 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; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1b5bb807b97..8f616af667a 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -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; # diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index d9e19571f81..f6006a87d47 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -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; diff --git a/sql/item.cc b/sql/item.cc index 11a9e88bdd6..084d006fef2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -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; } diff --git a/sql/sql_class.h b/sql/sql_class.h index e602b7d6d5f..9ed49c22119 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -773,7 +773,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; @@ -1152,7 +1152,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(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5fa8b37285e..586706be6c1 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -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() diff --git a/sql/sql_lex.h b/sql/sql_lex.h index aa3e81fd9c9..6e1e9fdecad 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -339,6 +339,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); @@ -423,7 +424,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 */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 47ecc57cf16..8f57ca5b08d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9134,7 +9134,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++) @@ -9143,6 +9144,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; @@ -9152,36 +9196,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++) @@ -9198,6 +9247,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; @@ -9236,9 +9286,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)) @@ -9303,32 +9355,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 @@ -9336,30 +9409,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) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 63638b618d9..fe009f89e76 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -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)); /* @@ -149,6 +149,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) @@ -156,7 +158,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; @@ -169,8 +190,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 { @@ -327,11 +349,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()) { @@ -350,7 +372,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; @@ -362,7 +384,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; |