492
484
keyuse Pointer to possible keys
493
485
*****************************************************************************/
488
Merge new key definitions to old ones, remove those not used in both.
490
This is called for OR between different levels.
492
To be able to do 'ref_or_null' we merge a comparison of a column
493
and 'column IS NULL' to one test. This is useful for sub select queries
494
that are internally transformed to something like:.
497
SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
500
KEY_FIELD::null_rejecting is processed as follows: @n
501
result has null_rejecting=true if it is set for both ORed references.
503
- (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
504
- (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
507
The result of this is that we're missing some 'ref' accesses.
508
OptimizerTeam: Fix this
510
static KEY_FIELD *merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, uint32_t and_level)
512
if (start == new_fields)
513
return start; // Impossible or
514
if (new_fields == end)
515
return start; // No new fields, skip all
517
KEY_FIELD *first_free=new_fields;
519
/* Mark all found fields in old array */
520
for (; new_fields != end ; new_fields++)
522
for (KEY_FIELD *old=start ; old != first_free ; old++)
524
if (old->field == new_fields->field)
527
NOTE: below const_item() call really works as "!used_tables()", i.e.
528
it can return false where it is feasible to make it return true.
530
The cause is as follows: Some of the tables are already known to be
531
const tables (the detection code is in make_join_statistics(),
532
above the update_ref_and_keys() call), but we didn't propagate
533
information about this: Table::const_table is not set to true, and
534
Item::update_used_tables() hasn't been called for each item.
535
The result of this is that we're missing some 'ref' accesses.
536
TODO: OptimizerTeam: Fix this
538
if (!new_fields->val->const_item())
541
If the value matches, we can use the key reference.
542
If not, we keep it until we have examined all new values
544
if (old->val->eq(new_fields->val, old->field->binary()))
546
old->level= and_level;
547
old->optimize= ((old->optimize & new_fields->optimize &
548
KEY_OPTIMIZE_EXISTS) |
549
((old->optimize | new_fields->optimize) &
550
KEY_OPTIMIZE_REF_OR_NULL));
551
old->null_rejecting= (old->null_rejecting &&
552
new_fields->null_rejecting);
555
else if (old->eq_func && new_fields->eq_func &&
556
old->val->eq_by_collation(new_fields->val,
557
old->field->binary(),
558
old->field->charset()))
561
old->level= and_level;
562
old->optimize= ((old->optimize & new_fields->optimize &
563
KEY_OPTIMIZE_EXISTS) |
564
((old->optimize | new_fields->optimize) &
565
KEY_OPTIMIZE_REF_OR_NULL));
566
old->null_rejecting= (old->null_rejecting &&
567
new_fields->null_rejecting);
569
else if (old->eq_func && new_fields->eq_func &&
570
((old->val->const_item() && old->val->is_null()) ||
571
new_fields->val->is_null()))
573
/* field = expression OR field IS NULL */
574
old->level= and_level;
575
old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
577
Remember the NOT NULL value unless the value does not depend
580
if (!old->val->used_tables() && old->val->is_null())
581
old->val= new_fields->val;
582
/* The referred expression can be NULL: */
583
old->null_rejecting= 0;
588
We are comparing two different const. In this case we can't
589
use a key-lookup on this so it's better to remove the value
590
and let the range optimzier handle it
592
if (old == --first_free) // If last item
594
*old= *first_free; // Remove old value
595
old--; // Retry this value
600
/* Remove all not used items */
601
for (KEY_FIELD *old=start ; old != first_free ;)
603
if (old->level != and_level)
604
{ // Not used in all levels
605
if (old == --first_free)
607
*old= *first_free; // Remove old value
616
Add a possible key to array of possible keys if it's usable as a key
618
@param key_fields Pointer to add key, if usable
619
@param and_level And level, to be stored in KEY_FIELD
620
@param cond Condition predicate
621
@param field Field used in comparision
622
@param eq_func True if we used =, <=> or IS NULL
623
@param value Value used for comparison with field
624
@param usable_tables Tables which can be used for key optimization
625
@param sargables IN/OUT Array of found sargable candidates
628
If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
629
table, we store this to be able to do not exists optimization later.
632
*key_fields is incremented if we stored a key in the array
634
static void add_key_field(KEY_FIELD **key_fields,
641
table_map usable_tables,
642
SARGABLE_PARAM **sargables)
644
uint32_t exists_optimize= 0;
645
if (!(field->flags & PART_KEY_FLAG))
647
// Don't remove column IS NULL on a LEFT JOIN table
648
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
649
!field->table->maybe_null || field->null_ptr)
650
return; // Not a key. Skip it
651
exists_optimize= KEY_OPTIMIZE_EXISTS;
652
assert(num_values == 1);
656
table_map used_tables=0;
658
for (uint32_t i=0; i<num_values; i++)
660
used_tables|=(value[i])->used_tables();
661
if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT)))
666
if (!(usable_tables & field->table->map))
668
if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
669
!field->table->maybe_null || field->null_ptr)
670
return; // Can't use left join optimize
671
exists_optimize= KEY_OPTIMIZE_EXISTS;
675
JoinTable *stat=field->table->reginfo.join_tab;
676
key_map possible_keys= field->key_start;
677
possible_keys&= field->table->keys_in_use_for_query;
678
stat[0].keys|= possible_keys; // Add possible keys
681
Save the following cases:
683
Field LIKE constant where constant doesn't start with a wildcard
684
Field = field2 where field2 is in a different table
691
stat[0].key_dependent|= used_tables;
694
for (uint32_t i=0; i<num_values; i++)
696
if (!(is_const&= value[i]->const_item()))
700
stat[0].const_keys|= possible_keys;
704
Save info to be able check whether this predicate can be
705
considered as sargable for range analisis after reading const tables.
706
We do not save info about equalities as update_const_equal_items
707
will take care of updating info on keys from sargable equalities.
710
(*sargables)->field= field;
711
(*sargables)->arg_value= value;
712
(*sargables)->num_values= num_values;
715
We can't always use indexes when comparing a string index to a
716
number. cmp_type() is checked to allow compare of dates to numbers.
717
eq_func is NEVER true when num_values > 1
722
Additional optimization: if we're processing
723
"t.key BETWEEN c1 AND c1" then proceed as if we were processing
725
TODO: This is a very limited fix. A more generic fix is possible.
727
A) Make equality propagation code be able to handle BETWEEN
728
(including cases like t1.key BETWEEN t2.key AND t3.key)
729
B) Make range optimizer to infer additional "t.key = c" equalities
730
and use them in equality propagation process (see details in
733
if ((cond->functype() != Item_func::BETWEEN) ||
734
((Item_func_between*) cond)->negated ||
735
!value[0]->eq(value[1], field->binary()))
740
if (field->result_type() == STRING_RESULT)
742
if ((*value)->result_type() != STRING_RESULT)
744
if (field->cmp_type() != (*value)->result_type())
750
We can't use indexes if the effective collation
751
of the operation differ from the field collation.
753
if (field->cmp_type() == STRING_RESULT &&
754
((Field_str*)field)->charset() != cond->compare_collation())
761
For the moment eq_func is always true. This slot is reserved for future
762
extensions where we want to remembers other things than just eq comparisons
765
/* Store possible eq field */
766
(*key_fields)->field= field;
767
(*key_fields)->eq_func= eq_func;
768
(*key_fields)->val= *value;
769
(*key_fields)->level= and_level;
770
(*key_fields)->optimize= exists_optimize;
772
If the condition has form "tbl.keypart = othertbl.field" and
773
othertbl.field can be NULL, there will be no matches if othertbl.field
775
We use null_rejecting in add_not_null_conds() to add
776
'othertbl.field IS NOT NULL' to tab->select_cond.
778
(*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC ||
779
cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
780
((*value)->type() == Item::FIELD_ITEM) &&
781
((Item_field*)*value)->field->maybe_null());
782
(*key_fields)->cond_guard= NULL;
787
Add possible keys to array of possible keys originated from a simple
790
@param key_fields Pointer to add key, if usable
791
@param and_level And level, to be stored in KEY_FIELD
792
@param cond Condition predicate
793
@param field Field used in comparision
794
@param eq_func True if we used =, <=> or IS NULL
795
@param value Value used for comparison with field
796
Is NULL for BETWEEN and IN
797
@param usable_tables Tables which can be used for key optimization
798
@param sargables IN/OUT Array of found sargable candidates
801
If field items f1 and f2 belong to the same multiple equality and
802
a key is added for f1, the the same key is added for f2.
805
*key_fields is incremented if we stored a key in the array
807
static void add_key_equal_fields(KEY_FIELD **key_fields,
810
Item_field *field_item,
814
table_map usable_tables,
815
SARGABLE_PARAM **sargables)
817
Field *field= field_item->field;
818
add_key_field(key_fields, and_level, cond, field,
819
eq_func, val, num_values, usable_tables, sargables);
820
Item_equal *item_equal= field_item->item_equal;
824
Add to the set of possible key values every substitution of
825
the field for an equal field included into item_equal
827
Item_equal_iterator it(*item_equal);
831
if (!field->eq(item->field))
833
add_key_field(key_fields, and_level, cond, item->field,
834
eq_func, val, num_values, usable_tables,
841
static void add_key_fields(JOIN *join,
842
KEY_FIELD **key_fields,
845
table_map usable_tables,
846
SARGABLE_PARAM **sargables)
848
if (cond->type() == Item_func::COND_ITEM)
850
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
851
KEY_FIELD *org_key_fields= *key_fields;
853
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
857
add_key_fields(join, key_fields, and_level, item, usable_tables,
859
for (; org_key_fields != *key_fields ; org_key_fields++)
860
org_key_fields->level= *and_level;
865
add_key_fields(join, key_fields, and_level, li++, usable_tables,
870
KEY_FIELD *start_key_fields= *key_fields;
872
add_key_fields(join, key_fields, and_level, item, usable_tables,
874
*key_fields=merge_key_fields(org_key_fields,start_key_fields,
875
*key_fields,++(*and_level));
882
Subquery optimization: Conditions that are pushed down into subqueries
883
are wrapped into Item_func_trig_cond. We process the wrapped condition
884
but need to set cond_guard for KeyUse elements generated from it.
887
if (cond->type() == Item::FUNC_ITEM &&
888
((Item_func*)cond)->functype() == Item_func::TRIG_COND_FUNC)
890
Item *cond_arg= ((Item_func*)cond)->arguments()[0];
891
if (!join->group_list && !join->order &&
893
join->unit->item->substype() == Item_subselect::IN_SUBS &&
894
!join->unit->is_union())
896
KEY_FIELD *save= *key_fields;
897
add_key_fields(join, key_fields, and_level, cond_arg, usable_tables,
899
// Indicate that this ref access candidate is for subquery lookup:
900
for (; save != *key_fields; save++)
901
save->cond_guard= ((Item_func_trig_cond*)cond)->get_trig_var();
907
/* If item is of type 'field op field/constant' add it to key_fields */
908
if (cond->type() != Item::FUNC_ITEM)
910
Item_func *cond_func= (Item_func*) cond;
911
switch (cond_func->select_optimize()) {
912
case Item_func::OPTIMIZE_NONE:
914
case Item_func::OPTIMIZE_KEY:
918
if (cond_func->key_item()->real_item()->type() == Item::FIELD_ITEM &&
919
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
921
values= cond_func->arguments()+1;
922
if (cond_func->functype() == Item_func::NE_FUNC &&
923
cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
924
!(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT))
926
assert(cond_func->functype() != Item_func::IN_FUNC ||
927
cond_func->argument_count() != 2);
928
add_key_equal_fields(key_fields, *and_level, cond_func,
929
(Item_field*) (cond_func->key_item()->real_item()),
931
cond_func->argument_count()-1,
932
usable_tables, sargables);
934
if (cond_func->functype() == Item_func::BETWEEN)
936
values= cond_func->arguments();
937
for (uint32_t i= 1 ; i < cond_func->argument_count() ; i++)
939
Item_field *field_item;
940
if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM
942
!(cond_func->arguments()[i]->used_tables() & OUTER_REF_TABLE_BIT))
944
field_item= (Item_field *) (cond_func->arguments()[i]->real_item());
945
add_key_equal_fields(key_fields, *and_level, cond_func,
946
field_item, 0, values, 1, usable_tables,
953
case Item_func::OPTIMIZE_OP:
955
bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC ||
956
cond_func->functype() == Item_func::EQUAL_FUNC);
958
if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM &&
959
!(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT))
961
add_key_equal_fields(key_fields, *and_level, cond_func,
962
(Item_field*) (cond_func->arguments()[0])->real_item(),
964
cond_func->arguments()+1, 1, usable_tables,
967
if (cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM &&
968
cond_func->functype() != Item_func::LIKE_FUNC &&
969
!(cond_func->arguments()[1]->used_tables() & OUTER_REF_TABLE_BIT))
971
add_key_equal_fields(key_fields, *and_level, cond_func,
972
(Item_field*) (cond_func->arguments()[1])->real_item(), equal_func,
973
cond_func->arguments(),1,usable_tables,
978
case Item_func::OPTIMIZE_NULL:
979
/* column_name IS [NOT] NULL */
980
if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM &&
981
!(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
983
Item *tmp=new Item_null;
984
if (unlikely(!tmp)) // Should never be true
986
add_key_equal_fields(key_fields, *and_level, cond_func,
987
(Item_field*) (cond_func->arguments()[0])->real_item(),
988
cond_func->functype() == Item_func::ISNULL_FUNC,
989
&tmp, 1, usable_tables, sargables);
992
case Item_func::OPTIMIZE_EQUAL:
993
Item_equal *item_equal= (Item_equal *) cond;
994
Item *const_item= item_equal->get_const();
995
Item_equal_iterator it(*item_equal);
1000
For each field field1 from item_equal consider the equality
1001
field1=const_item as a condition allowing an index access of the table
1002
with field1 by the keys value of field1.
1004
while ((item= it++))
1006
add_key_field(key_fields, *and_level, cond_func, item->field,
1007
true, &const_item, 1, usable_tables, sargables);
1013
Consider all pairs of different fields included into item_equal.
1014
For each of them (field1, field1) consider the equality
1015
field1=field2 as a condition allowing an index access of the table
1016
with field1 by the keys value of field2.
1018
Item_equal_iterator fi(*item_equal);
1019
while ((item= fi++))
1021
Field *field= item->field;
1022
while ((item= it++))
1024
if (!field->eq(item->field))
1026
add_key_field(key_fields, *and_level, cond_func, field,
1027
true, (Item **) &item, 1, usable_tables,
497
1039
Add all keys with uses 'field' for some keypart.
508
static int sort_keyuse(optimizer::KeyUse *a, optimizer::KeyUse *b)
1050
static void add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
1052
Field *field=key_field->field;
1053
Table *form= field->table;
1056
if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
1058
for (uint32_t key= 0 ; key < form->sizeKeys() ; key++)
1060
if (!(form->keys_in_use_for_query.test(key)))
1063
uint32_t key_parts= (uint32_t) form->key_info[key].key_parts;
1064
for (uint32_t part=0 ; part < key_parts ; part++)
1066
if (field->eq(form->key_info[key].key_part[part].field))
1068
keyuse.table= field->table;
1069
keyuse.val = key_field->val;
1071
keyuse.keypart=part;
1072
keyuse.keypart_map= (key_part_map) 1 << part;
1073
keyuse.used_tables=key_field->val->used_tables();
1074
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
1075
keyuse.null_rejecting= key_field->null_rejecting;
1076
keyuse.cond_guard= key_field->cond_guard;
1077
insert_dynamic(keyuse_array,(unsigned char*) &keyuse);
1084
static int sort_keyuse(KeyUse *a,KeyUse *b)
511
if (a->getTable()->tablenr != b->getTable()->tablenr)
512
return static_cast<int>((a->getTable()->tablenr - b->getTable()->tablenr));
513
if (a->getKey() != b->getKey())
514
return static_cast<int>((a->getKey() - b->getKey()));
515
if (a->getKeypart() != b->getKeypart())
516
return static_cast<int>((a->getKeypart() - b->getKeypart()));
1087
if (a->table->tablenr != b->table->tablenr)
1088
return (int) (a->table->tablenr - b->table->tablenr);
1089
if (a->key != b->key)
1090
return (int) (a->key - b->key);
1091
if (a->keypart != b->keypart)
1092
return (int) (a->keypart - b->keypart);
517
1093
// Place const values before other ones
518
if ((res= test((a->getUsedTables() & ~OUTER_REF_TABLE_BIT)) -
519
test((b->getUsedTables() & ~OUTER_REF_TABLE_BIT))))
1094
if ((res= test((a->used_tables & ~OUTER_REF_TABLE_BIT)) -
1095
test((b->used_tables & ~OUTER_REF_TABLE_BIT))))
521
1097
/* Place rows that are not 'OPTIMIZE_REF_OR_NULL' first */
522
return static_cast<int>(((a->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL) -
523
(b->getOptimizeFlags() & KEY_OPTIMIZE_REF_OR_NULL)));
1098
return (int) ((a->optimize & KEY_OPTIMIZE_REF_OR_NULL) -
1099
(b->optimize & KEY_OPTIMIZE_REF_OR_NULL));
1103
Add to KEY_FIELD array all 'ref' access candidates within nested join.
1105
This function populates KEY_FIELD array with entries generated from the
1106
ON condition of the given nested join, and does the same for nested joins
1107
contained within this nested join.
1109
@param[in] nested_join_table Nested join pseudo-table to process
1110
@param[in,out] end End of the key field array
1111
@param[in,out] and_level And-level
1112
@param[in,out] sargables Array of found sargable candidates
1116
We can add accesses to the tables that are direct children of this nested
1117
join (1), and are not inner tables w.r.t their neighbours (2).
1119
Example for #1 (outer brackets pair denotes nested join this function is
1122
... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond
1126
... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond
1128
In examples 1-2 for condition cond, we can add 'ref' access candidates to
1132
... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond
1134
Here we can add 'ref' access candidates for t1 and t2, but not for t3.
1136
static void add_key_fields_for_nj(JOIN *join,
1137
TableList *nested_join_table,
1139
uint32_t *and_level,
1140
SARGABLE_PARAM **sargables)
1142
List_iterator<TableList> li(nested_join_table->nested_join->join_list);
1143
List_iterator<TableList> li2(nested_join_table->nested_join->join_list);
1144
bool have_another = false;
1145
table_map tables= 0;
1147
assert(nested_join_table->nested_join);
1149
while ((table= li++) || (have_another && (li=li2, have_another=false,
1152
if (table->nested_join)
1154
if (!table->on_expr)
1156
/* It's a semi-join nest. Walk into it as if it wasn't a nest */
1159
li= List_iterator<TableList>(table->nested_join->join_list);
1162
add_key_fields_for_nj(join, table, end, and_level, sargables);
1165
if (!table->on_expr)
1166
tables |= table->table->map;
1168
if (nested_join_table->on_expr)
1169
add_key_fields(join, end, and_level, nested_join_table->on_expr, tables,
528
1174
Update keyuse array with all possible keys we can use to fetch rows.
7184
Send a description about what how the select will be done to stdout.
7186
void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
7187
bool distinct,const char *message)
7189
List<Item> field_list;
7190
List<Item> item_list;
7191
Session *session=join->session;
7192
select_result *result=join->result;
7193
Item *item_null= new Item_null();
7194
const CHARSET_INFO * const cs= system_charset_info;
7196
/* Don't log this into the slow query log */
7197
session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
7198
join->unit->offset_limit_cnt= 0;
7201
NOTE: the number/types of items pushed into item_list must be in sync with
7202
EXPLAIN column types as they're "defined" in Session::send_explain_fields()
7206
item_list.push_back(new Item_int((int32_t)
7207
join->select_lex->select_number));
7208
item_list.push_back(new Item_string(join->select_lex->type,
7209
strlen(join->select_lex->type), cs));
7210
for (uint32_t i=0 ; i < 7; i++)
7211
item_list.push_back(item_null);
7212
if (join->session->lex->describe & DESCRIBE_EXTENDED)
7213
item_list.push_back(item_null);
7215
item_list.push_back(new Item_string(message,strlen(message),cs));
7216
if (result->send_data(item_list))
7219
else if (join->select_lex == join->unit->fake_select_lex)
7222
here we assume that the query will return at least two rows, so we
7223
show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
7224
and no filesort will be actually done, but executing all selects in
7225
the UNION to provide precise EXPLAIN information will hardly be
7228
char table_name_buffer[NAME_LEN];
7231
item_list.push_back(new Item_null);
7233
item_list.push_back(new Item_string(join->select_lex->type,
7234
strlen(join->select_lex->type),
7238
Select_Lex *sl= join->unit->first_select();
7239
uint32_t len= 6, lastop= 0;
7240
memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
7241
for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
7244
lastop= snprintf(table_name_buffer + len, NAME_LEN - len,
7245
"%u,", sl->select_number);
7247
if (sl || len + lastop >= NAME_LEN)
7249
memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
7255
table_name_buffer[len - 1]= '>'; // change ',' to '>'
7257
item_list.push_back(new Item_string(table_name_buffer, len, cs));
7260
item_list.push_back(new Item_string(join_type_str[JT_ALL],
7261
strlen(join_type_str[JT_ALL]),
7264
item_list.push_back(item_null);
7266
item_list.push_back(item_null);
7268
item_list.push_back(item_null);
7270
item_list.push_back(item_null);
7272
if (join->session->lex->describe & DESCRIBE_EXTENDED)
7273
item_list.push_back(item_null);
7275
item_list.push_back(item_null);
7277
if (join->unit->global_parameters->order_list.first)
7278
item_list.push_back(new Item_string("Using filesort",
7281
item_list.push_back(new Item_string("", 0, cs));
7283
if (result->send_data(item_list))
7288
table_map used_tables=0;
7289
for (uint32_t i=0 ; i < join->tables ; i++)
7291
JoinTable *tab=join->join_tab+i;
7292
Table *table=tab->table;
7293
TableList *table_list= tab->table->pos_in_table_list;
7295
char buff1[512], buff2[512], buff3[512];
7296
char keylen_str_buf[64];
7297
String extra(buff, sizeof(buff),cs);
7298
char table_name_buffer[NAME_LEN];
7299
String tmp1(buff1,sizeof(buff1),cs);
7300
String tmp2(buff2,sizeof(buff2),cs);
7301
String tmp3(buff3,sizeof(buff3),cs);
7310
item_list.push_back(new Item_uint((uint32_t)
7311
join->select_lex->select_number));
7313
item_list.push_back(new Item_string(join->select_lex->type,
7314
strlen(join->select_lex->type),
7316
if (tab->type == JT_ALL && tab->select && tab->select->quick)
7318
quick_type= tab->select->quick->get_type();
7319
if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
7320
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
7321
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
7322
tab->type = JT_INDEX_MERGE;
7324
tab->type = JT_RANGE;
7327
if (table->derived_select_number)
7329
/* Derived table name generation */
7330
int len= snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
7332
table->derived_select_number);
7333
item_list.push_back(new Item_string(table_name_buffer, len, cs));
7337
TableList *real_table= table->pos_in_table_list;
7338
item_list.push_back(new Item_string(real_table->alias,
7339
strlen(real_table->alias),
7343
item_list.push_back(new Item_string(join_type_str[tab->type],
7344
strlen(join_type_str[tab->type]),
7346
/* Build "possible_keys" value and add it to item_list */
7347
if (tab->keys.any())
7350
for (j=0 ; j < table->s->keys ; j++)
7352
if (tab->keys.test(j))
7356
tmp1.append(table->key_info[j].name,
7357
strlen(table->key_info[j].name),
7358
system_charset_info);
7363
item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
7365
item_list.push_back(item_null);
7367
/* Build "key", "key_len", and "ref" values and add them to item_list */
7368
if (tab->ref.key_parts)
7370
KEY *key_info=table->key_info+ tab->ref.key;
7371
register uint32_t length;
7372
item_list.push_back(new Item_string(key_info->name,
7373
strlen(key_info->name),
7374
system_charset_info));
7375
length= int64_t2str(tab->ref.key_length, keylen_str_buf, 10) -
7377
item_list.push_back(new Item_string(keylen_str_buf, length,
7378
system_charset_info));
7379
for (StoredKey **ref=tab->ref.key_copy ; *ref ; ref++)
7383
tmp2.append((*ref)->name(), strlen((*ref)->name()),
7384
system_charset_info);
7386
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
7388
else if (tab->type == JT_NEXT)
7390
KEY *key_info=table->key_info+ tab->index;
7391
register uint32_t length;
7392
item_list.push_back(new Item_string(key_info->name,
7393
strlen(key_info->name),cs));
7394
length= int64_t2str(key_info->key_length, keylen_str_buf, 10) -
7396
item_list.push_back(new Item_string(keylen_str_buf,
7398
system_charset_info));
7399
item_list.push_back(item_null);
7401
else if (tab->select && tab->select->quick)
7403
tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
7404
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
7405
item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
7406
item_list.push_back(item_null);
7410
if (table_list->schema_table &&
7411
table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
7413
if (table_list->has_db_lookup_value)
7415
int f_idx= table_list->schema_table->getFirstColumnIndex();
7416
const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
7417
tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
7419
if (table_list->has_table_lookup_value)
7421
if (table_list->has_db_lookup_value)
7423
int f_idx= table_list->schema_table->getSecondColumnIndex();
7424
const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
7425
tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
7428
item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
7430
item_list.push_back(item_null);
7433
item_list.push_back(item_null);
7434
item_list.push_back(item_null);
7435
item_list.push_back(item_null);
7438
/* Add "rows" field to item_list. */
7439
if (table_list->schema_table)
7442
if (join->session->lex->describe & DESCRIBE_EXTENDED)
7443
item_list.push_back(item_null);
7445
item_list.push_back(item_null);
7449
double examined_rows;
7450
if (tab->select && tab->select->quick)
7451
examined_rows= rows2double(tab->select->quick->records);
7452
else if (tab->type == JT_NEXT || tab->type == JT_ALL)
7453
examined_rows= rows2double(tab->limit ? tab->limit :
7454
tab->table->file->records());
7456
examined_rows= join->best_positions[i].records_read;
7458
item_list.push_back(new Item_int((int64_t) (uint64_t) examined_rows,
7459
MY_INT64_NUM_DECIMAL_DIGITS));
7461
/* Add "filtered" field to item_list. */
7462
if (join->session->lex->describe & DESCRIBE_EXTENDED)
7466
f= (float) (100.0 * join->best_positions[i].records_read /
7468
item_list.push_back(new Item_float(f, 2));
7472
/* Build "Extra" field and add it to item_list. */
7473
bool key_read=table->key_read;
7474
if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
7475
table->covering_keys.test(tab->index))
7477
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
7478
!((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
7482
item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
7483
else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
7485
if (tab->packed_info & TAB_INFO_USING_INDEX)
7486
extra.append(STRING_WITH_LEN("; Using index"));
7487
if (tab->packed_info & TAB_INFO_USING_WHERE)
7488
extra.append(STRING_WITH_LEN("; Using where"));
7489
if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
7490
extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
7491
/* Skip initial "; "*/
7492
const char *str= extra.ptr();
7493
uint32_t len= extra.length();
7499
item_list.push_back(new Item_string(str, len, cs));
7503
uint32_t keyno= MAX_KEY;
7504
if (tab->ref.key_parts)
7505
keyno= tab->ref.key;
7506
else if (tab->select && tab->select->quick)
7507
keyno = tab->select->quick->index;
7509
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
7510
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
7511
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
7513
extra.append(STRING_WITH_LEN("; Using "));
7514
tab->select->quick->add_info_string(&extra);
7518
if (tab->use_quick == 2)
7521
* To print out the bitset in tab->keys, we go through
7522
* it 32 bits at a time. We need to do this to ensure
7523
* that the to_ulong() method will not throw an
7524
* out_of_range exception at runtime which would happen
7525
* if the bitset we were working with was larger than 64
7526
* bits on a 64-bit platform (for example).
7532
for (uint32_t pos= 0; pos < tab->keys.size(); pos+= 32)
7534
bitset<32> tmp(str, pos, 32);
7536
s << uppercase << hex << tmp.to_ulong();
7538
extra.append(STRING_WITH_LEN("; Range checked for each "
7539
"record (index map: 0x"));
7540
extra.append(s.str().c_str());
7543
else if (tab->select->cond)
7545
extra.append(STRING_WITH_LEN("; Using where"));
7550
if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
7551
extra.append(STRING_WITH_LEN("; Using index for group-by"));
7553
extra.append(STRING_WITH_LEN("; Using index"));
7555
if (table->reginfo.not_exists_optimize)
7556
extra.append(STRING_WITH_LEN("; Not exists"));
7558
if (table_list->schema_table &&
7559
table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
7561
if (!table_list->table_open_method)
7562
extra.append(STRING_WITH_LEN("; Skip_open_table"));
7563
else if (table_list->table_open_method == OPEN_FRM_ONLY)
7564
extra.append(STRING_WITH_LEN("; Open_frm_only"));
7566
extra.append(STRING_WITH_LEN("; Open_full_table"));
7567
if (table_list->has_db_lookup_value &&
7568
table_list->has_table_lookup_value)
7569
extra.append(STRING_WITH_LEN("; Scanned 0 databases"));
7570
else if (table_list->has_db_lookup_value ||
7571
table_list->has_table_lookup_value)
7572
extra.append(STRING_WITH_LEN("; Scanned 1 database"));
7574
extra.append(STRING_WITH_LEN("; Scanned all databases"));
7579
extra.append(STRING_WITH_LEN("; Using temporary"));
7584
extra.append(STRING_WITH_LEN("; Using filesort"));
7586
if (distinct & test_all_bits(used_tables,session->used_tables))
7587
extra.append(STRING_WITH_LEN("; Distinct"));
7589
if (tab->insideout_match_tab)
7591
extra.append(STRING_WITH_LEN("; LooseScan"));
7594
for (uint32_t part= 0; part < tab->ref.key_parts; part++)
7596
if (tab->ref.cond_guards[part])
7598
extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
7603
if (i > 0 && tab[-1].next_select == sub_select_cache)
7604
extra.append(STRING_WITH_LEN("; Using join buffer"));
7606
/* Skip initial "; "*/
7607
const char *str= extra.ptr();
7608
uint32_t len= extra.length();
7614
item_list.push_back(new Item_string(str, len, cs));
7616
// For next iteration
7617
used_tables|=table->map;
7618
if (result->send_data(item_list))
7622
for (Select_Lex_Unit *unit= join->select_lex->first_inner_unit();
7624
unit= unit->next_unit())
7626
if (mysql_explain_union(session, unit, result))
7632
bool mysql_explain_union(Session *session, Select_Lex_Unit *unit, select_result *result)
7635
Select_Lex *first= unit->first_select();
7637
for (Select_Lex *sl= first;
7639
sl= sl->next_select())
7641
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
7642
uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
7643
sl->type= (((&session->lex->select_lex)==sl)?
7644
(sl->first_inner_unit() || sl->next_select() ?
7645
"PRIMARY" : "SIMPLE"):
7647
((sl->linkage == DERIVED_TABLE_TYPE) ?
7649
((uncacheable & UNCACHEABLE_DEPENDENT) ?
7650
"DEPENDENT SUBQUERY":
7651
(uncacheable?"UNCACHEABLE SUBQUERY":
7653
((uncacheable & UNCACHEABLE_DEPENDENT) ?
7655
uncacheable?"UNCACHEABLE UNION":
7657
sl->options|= SELECT_DESCRIBE;
7659
if (unit->is_union())
7661
unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
7662
unit->fake_select_lex->type= "UNION RESULT";
7663
unit->fake_select_lex->options|= SELECT_DESCRIBE;
7664
if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
7666
res|= unit->cleanup();
7670
session->lex->current_select= first;
7671
unit->set_limit(unit->global_parameters);
7672
res= mysql_select(session, &first->ref_pointer_array,
7673
(TableList*) first->table_list.first,
7674
first->with_wild, first->item_list,
7676
first->order_list.elements +
7677
first->group_list.elements,
7678
(order_st*) first->order_list.first,
7679
(order_st*) first->group_list.first,
7681
first->options | session->options | SELECT_DESCRIBE,
7682
result, unit, first);
7684
return(res || session->is_error());
6541
7687
static void print_table_array(Session *session, String *str, TableList **table,
6542
7688
TableList **end)