6542
Send a description about what how the select will be done to stdout.
6544
void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
6545
bool distinct,const char *message)
6547
List<Item> field_list;
6548
List<Item> item_list;
6549
Session *session=join->session;
6550
select_result *result=join->result;
6551
Item *item_null= new Item_null();
6552
const CHARSET_INFO * const cs= system_charset_info;
6554
/* Don't log this into the slow query log */
6555
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
6556
join->unit->offset_limit_cnt= 0;
6559
NOTE: the number/types of items pushed into item_list must be in sync with
6560
EXPLAIN column types as they're "defined" in Session::send_explain_fields()
6564
item_list.push_back(new Item_int((int32_t)
6565
join->select_lex->select_number));
6566
item_list.push_back(new Item_string(join->select_lex->type,
6567
strlen(join->select_lex->type), cs));
6568
for (uint32_t i=0 ; i < 7; i++)
6569
item_list.push_back(item_null);
6570
if (join->session->lex->describe & DESCRIBE_EXTENDED)
6571
item_list.push_back(item_null);
6573
item_list.push_back(new Item_string(message,strlen(message),cs));
6574
if (result->send_data(item_list))
6577
else if (join->select_lex == join->unit->fake_select_lex)
6580
here we assume that the query will return at least two rows, so we
6581
show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
6582
and no filesort will be actually done, but executing all selects in
6583
the UNION to provide precise EXPLAIN information will hardly be
6586
char table_name_buffer[NAME_LEN];
6589
item_list.push_back(new Item_null);
6591
item_list.push_back(new Item_string(join->select_lex->type,
6592
strlen(join->select_lex->type),
6596
Select_Lex *sl= join->unit->first_select();
6597
uint32_t len= 6, lastop= 0;
6598
memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
6599
for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
6602
lastop= snprintf(table_name_buffer + len, NAME_LEN - len,
6603
"%u,", sl->select_number);
6605
if (sl || len + lastop >= NAME_LEN)
6607
memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
6613
table_name_buffer[len - 1]= '>'; // change ',' to '>'
6615
item_list.push_back(new Item_string(table_name_buffer, len, cs));
6618
item_list.push_back(new Item_string(access_method_str[AM_ALL].c_str(),
6619
access_method_str[AM_ALL].length(),
6622
item_list.push_back(item_null);
6624
item_list.push_back(item_null);
6626
item_list.push_back(item_null);
6628
item_list.push_back(item_null);
6630
if (join->session->lex->describe & DESCRIBE_EXTENDED)
6631
item_list.push_back(item_null);
6633
item_list.push_back(item_null);
6635
if (join->unit->global_parameters->order_list.first)
6636
item_list.push_back(new Item_string("Using filesort",
6639
item_list.push_back(new Item_string("", 0, cs));
6641
if (result->send_data(item_list))
6646
table_map used_tables=0;
6647
for (uint32_t i=0 ; i < join->tables ; i++)
6649
JoinTable *tab=join->join_tab+i;
6650
Table *table=tab->table;
6651
TableList *table_list= tab->table->pos_in_table_list;
6653
char buff1[512], buff2[512], buff3[512];
6654
char keylen_str_buf[64];
6655
String extra(buff, sizeof(buff),cs);
6656
char table_name_buffer[NAME_LEN];
6657
String tmp1(buff1,sizeof(buff1),cs);
6658
String tmp2(buff2,sizeof(buff2),cs);
6659
String tmp3(buff3,sizeof(buff3),cs);
6668
item_list.push_back(new Item_uint((uint32_t)
6669
join->select_lex->select_number));
6671
item_list.push_back(new Item_string(join->select_lex->type,
6672
strlen(join->select_lex->type),
6674
if (tab->type == AM_ALL && tab->select && tab->select->quick)
6676
quick_type= tab->select->quick->get_type();
6677
if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
6678
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
6679
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
6680
tab->type = AM_INDEX_MERGE;
6682
tab->type = AM_RANGE;
6685
if (table->derived_select_number)
6687
/* Derived table name generation */
6688
int len= snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
6690
table->derived_select_number);
6691
item_list.push_back(new Item_string(table_name_buffer, len, cs));
6695
TableList *real_table= table->pos_in_table_list;
6696
item_list.push_back(new Item_string(real_table->alias,
6697
strlen(real_table->alias),
6701
item_list.push_back(new Item_string(access_method_str[tab->type].c_str(),
6702
access_method_str[tab->type].length(),
6704
/* Build "possible_keys" value and add it to item_list */
6705
if (tab->keys.any())
6708
for (j=0 ; j < table->s->keys ; j++)
6710
if (tab->keys.test(j))
6714
tmp1.append(table->key_info[j].name,
6715
strlen(table->key_info[j].name),
6716
system_charset_info);
6721
item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
6723
item_list.push_back(item_null);
6725
/* Build "key", "key_len", and "ref" values and add them to item_list */
6726
if (tab->ref.key_parts)
6728
KEY *key_info=table->key_info+ tab->ref.key;
6729
register uint32_t length;
6730
item_list.push_back(new Item_string(key_info->name,
6731
strlen(key_info->name),
6732
system_charset_info));
6733
length= int64_t2str(tab->ref.key_length, keylen_str_buf, 10) -
6735
item_list.push_back(new Item_string(keylen_str_buf, length,
6736
system_charset_info));
6737
for (StoredKey **ref=tab->ref.key_copy ; *ref ; ref++)
6741
tmp2.append((*ref)->name(), strlen((*ref)->name()),
6742
system_charset_info);
6744
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
6746
else if (tab->type == AM_NEXT)
6748
KEY *key_info=table->key_info+ tab->index;
6749
register uint32_t length;
6750
item_list.push_back(new Item_string(key_info->name,
6751
strlen(key_info->name),cs));
6752
length= int64_t2str(key_info->key_length, keylen_str_buf, 10) -
6754
item_list.push_back(new Item_string(keylen_str_buf,
6756
system_charset_info));
6757
item_list.push_back(item_null);
6759
else if (tab->select && tab->select->quick)
6761
tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
6762
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
6763
item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
6764
item_list.push_back(item_null);
6768
if (table_list->schema_table &&
6769
table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
6771
if (table_list->has_db_lookup_value)
6773
int f_idx= table_list->schema_table->getFirstColumnIndex();
6774
const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
6775
tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
6777
if (table_list->has_table_lookup_value)
6779
if (table_list->has_db_lookup_value)
6781
int f_idx= table_list->schema_table->getSecondColumnIndex();
6782
const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
6783
tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
6786
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
6788
item_list.push_back(item_null);
6791
item_list.push_back(item_null);
6792
item_list.push_back(item_null);
6793
item_list.push_back(item_null);
6796
/* Add "rows" field to item_list. */
6797
if (table_list->schema_table)
6800
if (join->session->lex->describe & DESCRIBE_EXTENDED)
6801
item_list.push_back(item_null);
6803
item_list.push_back(item_null);
6807
double examined_rows;
6808
if (tab->select && tab->select->quick)
6809
examined_rows= rows2double(tab->select->quick->records);
6810
else if (tab->type == AM_NEXT || tab->type == AM_ALL)
6811
examined_rows= rows2double(tab->limit ? tab->limit :
6812
tab->table->file->records());
6815
optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
6816
examined_rows= cur_pos.getFanout();
6819
item_list.push_back(new Item_int((int64_t) (uint64_t) examined_rows,
6820
MY_INT64_NUM_DECIMAL_DIGITS));
6822
/* Add "filtered" field to item_list. */
6823
if (join->session->lex->describe & DESCRIBE_EXTENDED)
6828
optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
6829
f= (float) (100.0 * cur_pos.getFanout() /
6832
item_list.push_back(new Item_float(f, 2));
6836
/* Build "Extra" field and add it to item_list. */
6837
bool key_read=table->key_read;
6838
if ((tab->type == AM_NEXT || tab->type == AM_CONST) &&
6839
table->covering_keys.test(tab->index))
6841
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
6842
!((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
6846
item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
6847
else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
6849
if (tab->packed_info & TAB_INFO_USING_INDEX)
6850
extra.append(STRING_WITH_LEN("; Using index"));
6851
if (tab->packed_info & TAB_INFO_USING_WHERE)
6852
extra.append(STRING_WITH_LEN("; Using where"));
6853
if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
6854
extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
6855
/* Skip initial "; "*/
6856
const char *str= extra.ptr();
6857
uint32_t len= extra.length();
6863
item_list.push_back(new Item_string(str, len, cs));
6867
uint32_t keyno= MAX_KEY;
6868
if (tab->ref.key_parts)
6869
keyno= tab->ref.key;
6870
else if (tab->select && tab->select->quick)
6871
keyno = tab->select->quick->index;
6873
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
6874
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
6875
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
6877
extra.append(STRING_WITH_LEN("; Using "));
6878
tab->select->quick->add_info_string(&extra);
6882
if (tab->use_quick == 2)
6885
* To print out the bitset in tab->keys, we go through
6886
* it 32 bits at a time. We need to do this to ensure
6887
* that the to_ulong() method will not throw an
6888
* out_of_range exception at runtime which would happen
6889
* if the bitset we were working with was larger than 64
6890
* bits on a 64-bit platform (for example).
6896
for (uint32_t pos= 0; pos < tab->keys.size(); pos+= 32)
6898
bitset<32> tmp(str, pos, 32);
6900
s << uppercase << hex << tmp.to_ulong();
6902
extra.append(STRING_WITH_LEN("; Range checked for each "
6903
"record (index map: 0x"));
6904
extra.append(s.str().c_str());
6907
else if (tab->select->cond)
6909
extra.append(STRING_WITH_LEN("; Using where"));
6914
if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
6915
extra.append(STRING_WITH_LEN("; Using index for group-by"));
6917
extra.append(STRING_WITH_LEN("; Using index"));
6919
if (table->reginfo.not_exists_optimize)
6920
extra.append(STRING_WITH_LEN("; Not exists"));
6922
if (table_list->schema_table &&
6923
table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
6925
if (!table_list->table_open_method)
6926
extra.append(STRING_WITH_LEN("; Skip_open_table"));
6927
else if (table_list->table_open_method == OPEN_FRM_ONLY)
6928
extra.append(STRING_WITH_LEN("; Open_frm_only"));
6930
extra.append(STRING_WITH_LEN("; Open_full_table"));
6931
if (table_list->has_db_lookup_value &&
6932
table_list->has_table_lookup_value)
6933
extra.append(STRING_WITH_LEN("; Scanned 0 databases"));
6934
else if (table_list->has_db_lookup_value ||
6935
table_list->has_table_lookup_value)
6936
extra.append(STRING_WITH_LEN("; Scanned 1 database"));
6938
extra.append(STRING_WITH_LEN("; Scanned all databases"));
6943
extra.append(STRING_WITH_LEN("; Using temporary"));
6948
extra.append(STRING_WITH_LEN("; Using filesort"));
6950
if (distinct & test_all_bits(used_tables,session->used_tables))
6951
extra.append(STRING_WITH_LEN("; Distinct"));
6953
if (tab->insideout_match_tab)
6955
extra.append(STRING_WITH_LEN("; LooseScan"));
6958
for (uint32_t part= 0; part < tab->ref.key_parts; part++)
6960
if (tab->ref.cond_guards[part])
6962
extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
6967
if (i > 0 && tab[-1].next_select == sub_select_cache)
6968
extra.append(STRING_WITH_LEN("; Using join buffer"));
6970
/* Skip initial "; "*/
6971
const char *str= extra.ptr();
6972
uint32_t len= extra.length();
6978
item_list.push_back(new Item_string(str, len, cs));
6980
// For next iteration
6981
used_tables|=table->map;
6982
if (result->send_data(item_list))
6986
for (Select_Lex_Unit *unit= join->select_lex->first_inner_unit();
6988
unit= unit->next_unit())
6990
if (mysql_explain_union(session, unit, result))
6996
bool mysql_explain_union(Session *session, Select_Lex_Unit *unit, select_result *result)
6999
Select_Lex *first= unit->first_select();
7001
for (Select_Lex *sl= first;
7003
sl= sl->next_select())
7005
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
7006
uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
7007
sl->type= (((&session->lex->select_lex)==sl)?
7008
(sl->first_inner_unit() || sl->next_select() ?
7009
"PRIMARY" : "SIMPLE"):
7011
((sl->linkage == DERIVED_TABLE_TYPE) ?
7013
((uncacheable & UNCACHEABLE_DEPENDENT) ?
7014
"DEPENDENT SUBQUERY":
7015
(uncacheable?"UNCACHEABLE SUBQUERY":
7017
((uncacheable & UNCACHEABLE_DEPENDENT) ?
7019
uncacheable?"UNCACHEABLE UNION":
7021
sl->options|= SELECT_DESCRIBE;
7023
if (unit->is_union())
7025
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
7026
unit->fake_select_lex->type= "UNION RESULT";
7027
unit->fake_select_lex->options|= SELECT_DESCRIBE;
7028
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
7030
res|= unit->cleanup();
7034
session->lex->current_select= first;
7035
unit->set_limit(unit->global_parameters);
7036
res= mysql_select(session, &first->ref_pointer_array,
7037
(TableList*) first->table_list.first,
7038
first->with_wild, first->item_list,
7040
first->order_list.elements +
7041
first->group_list.elements,
7042
(order_st*) first->order_list.first,
7043
(order_st*) first->group_list.first,
7045
first->options | session->options | SELECT_DESCRIBE,
7046
result, unit, first);
7048
return(res || session->is_error());
7051
6541
static void print_table_array(Session *session, String *str, TableList **table,
7052
6542
TableList **end)