summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc153
1 files changed, 71 insertions, 82 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d071743aec4..b87a79cc2c6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -144,7 +144,6 @@ static void init_sum_functions(Item_sum **func);
static bool update_sum_func(Item_sum **func);
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
bool distinct, const char *message=NullS);
-static void describe_info(THD *thd, const char *info);
/*
This handles SELECT with and without UNION
@@ -154,19 +153,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
{
int res;
register SELECT_LEX *select_lex = &lex->select_lex;
- if (select_lex->next_select_in_list())
- {
- /* Fix tables 'to-be-unioned-from' list to point at opened tables */
- for (SELECT_LEX *sl= select_lex;
- sl;
- sl= sl->next_select_in_list())
- {
- for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
- cursor;
- cursor=cursor->next)
- cursor->table= cursor->table_list->table;
- }
- }
+ fix_tables_pointers(select_lex);
if (select_lex->next_select())
res=mysql_union(thd,lex,result);
else
@@ -178,7 +165,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
select_lex->having,
(ORDER*) lex->proc_list.first,
select_lex->options | thd->options,
- result, &(lex->unit), 0);
+ result, &(lex->unit), &(lex->select_lex), 0);
if (res && result)
result->abort();
if (res || thd->net.report_error)
@@ -190,6 +177,22 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
return res;
}
+void fix_tables_pointers(SELECT_LEX *select_lex)
+{
+ if (select_lex->next_select_in_list())
+ {
+ /* Fix tables 'to-be-unioned-from' list to point at opened tables */
+ for (SELECT_LEX *sl= select_lex;
+ sl;
+ sl= sl->next_select_in_list())
+ {
+ for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
+ cursor;
+ cursor=cursor->next)
+ cursor->table= cursor->table_list->table;
+ }
+ }
+}
/*****************************************************************************
** check fields, find best join, do the select and output fields.
@@ -209,7 +212,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
SELECT_LEX_UNIT *unit, bool fake_select_lex)
{
DBUG_ENTER("JOIN::prepare");
-
+
conds= conds_init;
order= order_init;
group_list= group_init;
@@ -344,7 +347,7 @@ int
JOIN::optimize()
{
DBUG_ENTER("JOIN::optimize");
-
+
#ifdef HAVE_REF_TO_FIELDS // Not done yet
/* Add HAVING to WHERE if possible */
if (having && !group_list && ! sum_func_count)
@@ -389,11 +392,8 @@ JOIN::optimize()
}
if (select_options & SELECT_DESCRIBE)
{
- if (union_part)
- select_describe(this, false, false, false,
- "Select tables optimized away");
- else
- describe_info(thd, "Select tables optimized away");
+ select_describe(this, false, false, false,
+ "Select tables optimized away");
delete procedure;
DBUG_RETURN(1);
}
@@ -647,10 +647,7 @@ JOIN::exec()
error=0;
if (select_options & SELECT_DESCRIBE)
{
- if (union_part)
- select_describe(this, false, false, false, "No tables used");
- else
- describe_info(thd, "No tables used");
+ select_describe(this, false, false, false, "No tables used");
}
else
{
@@ -674,16 +671,16 @@ JOIN::exec()
if (zero_result_cause)
{
- if (select_options & SELECT_DESCRIBE && union_part)
+ if (select_options & SELECT_DESCRIBE)
select_describe(this, false, false, false, zero_result_cause);
else
- error=return_zero_rows(result, tables_list, fields_list,
- tmp_table_param.sum_func_count != 0 &&
- !group_list,
- select_options,
- zero_result_cause,
- having,procedure,
- unit);
+ error= return_zero_rows(result, tables_list, fields_list,
+ tmp_table_param.sum_func_count != 0 &&
+ !group_list,
+ select_options,
+ zero_result_cause,
+ having,procedure,
+ unit);
DBUG_VOID_RETURN;
}
@@ -1004,7 +1001,8 @@ int
mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
ORDER *order, ORDER *group,Item *having, ORDER *proc_param,
ulong select_options, select_result *result,
- SELECT_LEX_UNIT *unit, bool fake_select_lex)
+ SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex,
+ bool fake_select_lex)
{
JOIN *join = new JOIN(thd, fields, select_options, result);
@@ -1013,7 +1011,7 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds,
thd->used_tables=0; // Updated by setup_fields
if (join->prepare(tables, conds, order, group, having, proc_param,
- &(thd->lex.select_lex), unit, fake_select_lex))
+ select_lex, unit, fake_select_lex))
{
DBUG_RETURN(-1);
}
@@ -3087,11 +3085,6 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
{
DBUG_ENTER("return_zero_rows");
- if (select_options & SELECT_DESCRIBE)
- {
- describe_info(current_thd, info);
- DBUG_RETURN(0);
- }
if (procedure)
{
if (result->prepare(fields, unit)) // This hasn't been done yet
@@ -3725,6 +3718,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->blob_ptr_size=mi_portable_sizeof_char_ptr;
table->map=1;
table->tmp_table= TMP_TABLE;
+ table->derived_select_number= 0;
table->db_low_byte_first=1; // True for HEAP and MyISAM
table->temp_pool_slot = temp_pool_slot;
@@ -7139,7 +7133,6 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
Item *item;
List<Item> item_list;
THD *thd=join->thd;
- MYSQL_LOCK *save_lock;
SELECT_LEX *select_lex = &(join->thd->lex.select_lex);
select_result *result=join->result;
DBUG_ENTER("select_describe");
@@ -7147,28 +7140,13 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
/* Don't log this into the slow query log */
select_lex->options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
join->unit->offset_limit_cnt= 0;
- if (thd->lex.select == select_lex)
- {
- field_list.push_back(new Item_empty_string("table",NAME_LEN));
- field_list.push_back(new Item_empty_string("type",10));
- field_list.push_back(item=new Item_empty_string("possible_keys",
- NAME_LEN*MAX_KEY));
- item->maybe_null=1;
- field_list.push_back(item=new Item_empty_string("key",NAME_LEN));
- item->maybe_null=1;
- field_list.push_back(item=new Item_int("key_len",0,3));
- item->maybe_null=1;
- field_list.push_back(item=new Item_empty_string("ref",
- NAME_LEN*MAX_REF_PARTS));
- item->maybe_null=1;
- field_list.push_back(new Item_real("rows",0.0,0,10));
- field_list.push_back(new Item_empty_string("Extra",255));
- if (result->send_fields(field_list,1))
- return;
- }
if (message)
{
+ item_list.push_back(new Item_int((int)thd->lex.select->select_number));
+ item_list.push_back(new Item_string(thd->lex.select->type,
+ strlen(thd->lex.select->type),
+ default_charset_info));
item_list.push_back(new Item_empty_string("",0));
item_list.push_back(new Item_empty_string("",0));
item_list.push_back(new Item_empty_string("",0));
@@ -7192,9 +7170,24 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
String tmp1(buff1,sizeof(buff1),default_charset_info);
String tmp2(buff2,sizeof(buff2),default_charset_info);
item_list.empty();
+ item_list.push_back(new Item_int((int)thd->lex.select->select_number));
+ item_list.push_back(new Item_string(thd->lex.select->type,
+ strlen(thd->lex.select->type),
+ default_charset_info));
if (tab->type == JT_ALL && tab->select && tab->select->quick)
tab->type= JT_RANGE;
- item_list.push_back(new Item_string(table->table_name,strlen(table->table_name),default_charset_info));
+ if (table->tmp_table == TMP_TABLE && table->derived_select_number != 0)
+ {
+ // Derived table name generation
+ buff[512];
+ int len= my_snprintf(buff, 512, "<derived%u>",
+ table->derived_select_number);
+ item_list.push_back(new Item_string(buff, len, default_charset_info));
+ }
+ else
+ item_list.push_back(new Item_string(table->table_name,
+ strlen(table->table_name),
+ default_charset_info));
item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type]),default_charset_info));
tmp1.length(0); tmp2.length(0);
key_map bits;
@@ -7311,29 +7304,25 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
result->send_error(0,NullS);
}
}
- if (!join->thd->lex.select->next_select())
- {
- save_lock=thd->lock;
- thd->lock=(MYSQL_LOCK *)0;
- result->send_eof();
- thd->lock=save_lock;
- }
DBUG_VOID_RETURN;
}
-
-static void describe_info(THD *thd, const char *info)
+int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type,
+ select_result *result)
{
- List<Item> field_list;
- String *packet= &thd->packet;
+ select_lex->type= type;
+ thd->lex.select= select_lex;
+ SELECT_LEX_UNIT *unit= select_lex->master_unit();
+ int res= mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first,
+ select_lex->item_list,
+ select_lex->where,
+ (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, 0);
- /* Don't log this into the slow query log */
- thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
- field_list.push_back(new Item_empty_string("Comment",80));
- if (send_fields(thd,field_list,1))
- return; /* purecov: inspected */
- packet->length(0);
- net_store_data(packet,info);
- if (!my_net_write(&thd->net,(char*) packet->ptr(),packet->length()))
- send_eof(&thd->net);
+ return res;
}
+