720
725
Item_func::Functype type,Item *value);
721
726
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
723
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts);
724
static ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
728
static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts);
729
static ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
725
730
SEL_ARG *tree, bool update_tbl_stats,
726
uint32_t *mrr_flags, uint32_t *bufsize,
731
uint *mrr_flags, uint *bufsize,
727
732
COST_VECT *cost);
728
733
//bool update_tbl_stats);
729
/*static ha_rows check_quick_keys(PARAM *param,uint32_t index,SEL_ARG *key_tree,
730
unsigned char *min_key, uint32_t min_key_flag, int,
731
unsigned char *max_key, uint32_t max_key_flag, int);
734
/*static ha_rows check_quick_keys(PARAM *param,uint index,SEL_ARG *key_tree,
735
uchar *min_key, uint min_key_flag, int,
736
uchar *max_key, uint max_key_flag, int);
734
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint32_t index,
735
SEL_ARG *key_tree, uint32_t mrr_flags,
736
uint32_t mrr_buf_size, MEM_ROOT *alloc);
739
QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
740
SEL_ARG *key_tree, uint mrr_flags,
741
uint mrr_buf_size, MEM_ROOT *alloc);
737
742
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
738
743
bool index_read_must_be_used,
739
744
bool update_tbl_stats,
753
758
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
755
761
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
756
762
const char *msg);
757
static void print_ror_scans_arr(Table *table, const char *msg,
763
static void print_ror_scans_arr(TABLE *table, const char *msg,
758
764
struct st_ror_scan_info **start,
759
765
struct st_ror_scan_info **end);
766
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
761
769
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
762
770
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
763
771
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
764
772
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
765
773
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
766
uint32_t clone_flag);
767
775
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
768
776
bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
769
SEL_ARG *key_tree, unsigned char *min_key,uint32_t min_key_flag,
770
unsigned char *max_key,uint32_t max_key_flag);
777
SEL_ARG *key_tree, uchar *min_key,uint min_key_flag,
778
uchar *max_key,uint max_key_flag);
771
779
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
773
781
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
774
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
782
static bool null_part_in_key(KEY_PART *key_part, const uchar *key,
776
784
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
1602
1633
use_count=0; elements=1;
1605
SEL_ARG::SEL_ARG(Field *f,const unsigned char *min_value_arg,
1606
const unsigned char *max_value_arg)
1636
SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg,
1637
const uchar *max_value_arg)
1607
1638
:min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()),
1608
elements(1), use_count(1), field(f), min_value((unsigned char*) min_value_arg),
1609
max_value((unsigned char*) max_value_arg), next(0),prev(0),
1639
elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg),
1640
max_value((uchar*) max_value_arg), next(0),prev(0),
1610
1641
next_key_part(0),color(BLACK),type(KEY_RANGE)
1612
1643
left=right= &null_element;
1615
SEL_ARG::SEL_ARG(Field *field_,uint8_t part_,
1616
unsigned char *min_value_, unsigned char *max_value_,
1617
uint8_t min_flag_,uint8_t max_flag_,uint8_t maybe_flag_)
1646
SEL_ARG::SEL_ARG(Field *field_,uint8 part_,
1647
uchar *min_value_, uchar *max_value_,
1648
uint8 min_flag_,uint8 max_flag_,uint8 maybe_flag_)
1618
1649
:min_flag(min_flag_),max_flag(max_flag_),maybe_flag(maybe_flag_),
1619
1650
part(part_),maybe_null(field_->real_maybe_null()), elements(1),use_count(1),
1620
1651
field(field_), min_value(min_value_), max_value(max_value_),
1998
2025
bool have_min, have_max;
1999
2026
KEY_PART_INFO *min_max_arg_part;
2000
uint32_t group_prefix_len;
2001
uint32_t used_key_parts;
2002
uint32_t group_key_parts;
2027
uint group_prefix_len;
2028
uint used_key_parts;
2029
uint group_key_parts;
2003
2030
KEY *index_info;
2005
uint32_t key_infix_len;
2006
unsigned char key_infix[MAX_KEY_LENGTH];
2033
uchar key_infix[MAX_KEY_LENGTH];
2007
2034
SEL_TREE *range_tree; /* Represents all range predicates in the query. */
2008
2035
SEL_ARG *index_tree; /* The SEL_ARG sub-tree corresponding to index_info. */
2009
uint32_t param_idx; /* Index of used key in param->key. */
2036
uint param_idx; /* Index of used key in param->key. */
2010
2037
/* Number of records selected by the ranges in index_tree. */
2012
2039
ha_rows quick_prefix_records;
2014
2041
TRP_GROUP_MIN_MAX(bool have_min_arg, bool have_max_arg,
2015
2042
KEY_PART_INFO *min_max_arg_part_arg,
2016
uint32_t group_prefix_len_arg, uint32_t used_key_parts_arg,
2017
uint32_t group_key_parts_arg, KEY *index_info_arg,
2018
uint32_t index_arg, uint32_t key_infix_len_arg,
2019
unsigned char *key_infix_arg,
2043
uint group_prefix_len_arg, uint used_key_parts_arg,
2044
uint group_key_parts_arg, KEY *index_info_arg,
2045
uint index_arg, uint key_infix_len_arg,
2046
uchar *key_infix_arg,
2020
2047
SEL_TREE *tree_arg, SEL_ARG *index_tree_arg,
2021
uint32_t param_idx_arg, ha_rows quick_prefix_records_arg)
2048
uint param_idx_arg, ha_rows quick_prefix_records_arg)
2022
2049
: have_min(have_min_arg), have_max(have_max_arg),
2023
2050
min_max_arg_part(min_max_arg_part_arg),
2024
2051
group_prefix_len(group_prefix_len_arg), used_key_parts(used_key_parts_arg),
3445
3523
my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark, sizeof(ROR_SCAN_INFO*),
3446
3524
(qsort_cmp)cmp_ror_scan_info_covering);
3448
print_ror_scans_arr(param->table,
3526
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3449
3527
"remaining scans",
3450
ror_scan_mark, ror_scans_end);
3528
ror_scan_mark, ror_scans_end););
3452
3530
/* I=I-first(I) */
3453
3531
total_cost += (*ror_scan_mark)->index_read_cost;
3454
3532
records += (*ror_scan_mark)->records;
3533
DBUG_PRINT("info", ("Adding scan on %s",
3534
param->table->key_info[(*ror_scan_mark)->keynr].name));
3455
3535
if (total_cost > read_time)
3457
3537
/* F=F-covered by first(I) */
3458
3538
bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
3459
3539
all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields);
3460
3540
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
3462
3542
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
3466
3546
Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with
3467
3547
cost total_cost.
3469
print_ror_scans_arr(param->table,
3549
DBUG_PRINT("info", ("Covering ROR-intersect scans cost: %g", total_cost));
3550
DBUG_EXECUTE("info", print_ror_scans_arr(param->table,
3470
3551
"creating covering ROR-intersect",
3471
tree->ror_scans, ror_scan_mark);
3552
tree->ror_scans, ror_scan_mark););
3473
3554
/* Add priority queue use cost. */
3474
3555
total_cost += rows2double(records)*
3475
3556
log((double)(ror_scan_mark - tree->ror_scans)) /
3476
3557
(TIME_FOR_COMPARE_ROWID * M_LN2);
3558
DBUG_PRINT("info", ("Covering ROR-intersect full cost: %g", total_cost));
3478
3560
if (total_cost > read_time)
3481
3563
TRP_ROR_INTERSECT *trp;
3482
3564
if (!(trp= new (param->mem_root) TRP_ROR_INTERSECT))
3484
uint32_t best_num= (ror_scan_mark - tree->ror_scans);
3566
uint best_num= (ror_scan_mark - tree->ror_scans);
3485
3567
if (!(trp->first_scan= (ROR_SCAN_INFO**)alloc_root(param->mem_root,
3486
3568
sizeof(ROR_SCAN_INFO*)*
3489
3571
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
3490
3572
trp->last_scan= trp->first_scan + best_num;
3491
3573
trp->is_covering= true;
7233
7344
if (last_range)
7235
7346
/* Read the next record in the same range with prefix after cur_prefix. */
7236
assert(cur_prefix != 0);
7347
DBUG_ASSERT(cur_prefix != 0);
7237
7348
result= file->index_read_map(record, cur_prefix, keypart_map,
7238
7349
HA_READ_AFTER_KEY);
7239
7350
if (result || (file->compare_key(file->end_range) <= 0))
7351
DBUG_RETURN(result);
7243
uint32_t count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7354
uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
7244
7355
if (count == 0)
7246
7357
/* Ranges have already been used up before. None is left for read. */
7248
return(HA_ERR_END_OF_FILE);
7359
DBUG_RETURN(HA_ERR_END_OF_FILE);
7250
7361
last_range= *(cur_range++);
7252
start_key.key= (const unsigned char*) last_range->min_key;
7253
start_key.length= cmin(last_range->min_length, (uint16_t)prefix_length);
7363
start_key.key= (const uchar*) last_range->min_key;
7364
start_key.length= min(last_range->min_length, prefix_length);
7254
7365
start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7255
7366
start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7256
7367
(last_range->flag & EQ_RANGE) ?
7257
7368
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7258
end_key.key= (const unsigned char*) last_range->max_key;
7259
end_key.length= cmin(last_range->max_length, (uint16_t)prefix_length);
7369
end_key.key= (const uchar*) last_range->max_key;
7370
end_key.length= min(last_range->max_length, prefix_length);
7260
7371
end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7262
7373
We use READ_AFTER_KEY here because if we are reading on a key
7680
7793
* Implementation of QUICK_GROUP_MIN_MAX_SELECT
7681
7794
*******************************************************************************/
7683
static inline uint32_t get_field_keypart(KEY *index, Field *field);
7684
static inline SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree,
7685
PARAM *param, uint32_t *param_idx);
7796
static inline uint get_field_keypart(KEY *index, Field *field);
7797
static inline SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree,
7798
PARAM *param, uint *param_idx);
7686
7799
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7687
7800
KEY_PART_INFO *first_non_group_part,
7688
7801
KEY_PART_INFO *min_max_arg_part,
7689
7802
KEY_PART_INFO *last_part, THD *thd,
7690
unsigned char *key_infix, uint32_t *key_infix_len,
7803
uchar *key_infix, uint *key_infix_len,
7691
7804
KEY_PART_INFO **first_non_infix_part);
7693
7806
check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
7694
7807
Field::imagetype image_type);
7697
cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
7698
uint32_t group_key_parts, SEL_TREE *range_tree,
7810
cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
7811
uint group_key_parts, SEL_TREE *range_tree,
7699
7812
SEL_ARG *index_tree, ha_rows quick_prefix_records,
7700
7813
bool have_min, bool have_max,
7701
7814
double *read_cost, ha_rows *records);
7835
7948
THD *thd= param->thd;
7836
7949
JOIN *join= thd->lex->current_select->join;
7837
Table *table= param->table;
7950
TABLE *table= param->table;
7838
7951
bool have_min= false; /* true if there is a MIN function. */
7839
7952
bool have_max= false; /* true if there is a MAX function. */
7840
7953
Item_field *min_max_arg_item= NULL; // The argument of all MIN/MAX functions
7841
7954
KEY_PART_INFO *min_max_arg_part= NULL; /* The corresponding keypart. */
7842
uint32_t group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
7955
uint group_prefix_len= 0; /* Length (in bytes) of the key prefix. */
7843
7956
KEY *index_info= NULL; /* The index chosen for data access. */
7844
uint32_t index= 0; /* The id of the chosen index. */
7845
uint32_t group_key_parts= 0; // Number of index key parts in the group prefix.
7846
uint32_t used_key_parts= 0; /* Number of index key parts used for access. */
7847
unsigned char key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
7848
uint32_t key_infix_len= 0; /* Length of key_infix. */
7957
uint index= 0; /* The id of the chosen index. */
7958
uint group_key_parts= 0; // Number of index key parts in the group prefix.
7959
uint used_key_parts= 0; /* Number of index key parts used for access. */
7960
uchar key_infix[MAX_KEY_LENGTH]; /* Constants from equality predicates.*/
7961
uint key_infix_len= 0; /* Length of key_infix. */
7849
7962
TRP_GROUP_MIN_MAX *read_plan= NULL; /* The eventually constructed TRP. */
7850
uint32_t key_part_nr;
7851
order_st *tmp_group;
7853
7966
Item_field *item_field;
7967
DBUG_ENTER("get_best_group_min_max");
7855
7969
/* Perform few 'cheap' tests whether this access method is applicable. */
7857
return(NULL); /* This is not a select statement. */
7971
DBUG_RETURN(NULL); /* This is not a select statement. */
7858
7972
if ((join->tables != 1) || /* The query must reference one table. */
7859
7973
((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7860
7974
(!join->select_distinct)) ||
7861
7975
(join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7863
7977
if (table->s->keys == 0) /* There are no indexes to use. */
7866
7980
/* Analyze the query in more detail. */
7867
7981
List_iterator<Item> select_items_it(join->fields_list);
7869
7983
/* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
7870
7984
if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
7872
7986
if (join->sum_funcs[0])
7874
7988
Item_sum *min_max_item;
7926
8040
KEY_PART_INFO *last_part= NULL;
7927
8041
KEY_PART_INFO *first_non_group_part= NULL;
7928
8042
KEY_PART_INFO *first_non_infix_part= NULL;
7929
uint32_t key_infix_parts= 0;
7930
uint32_t cur_group_key_parts= 0;
7931
uint32_t cur_group_prefix_len= 0;
8043
uint key_infix_parts= 0;
8044
uint cur_group_key_parts= 0;
8045
uint cur_group_prefix_len= 0;
7932
8046
/* Cost-related variables for the best index so far. */
7933
8047
double best_read_cost= DBL_MAX;
7934
8048
ha_rows best_records= 0;
7935
8049
SEL_ARG *best_index_tree= NULL;
7936
8050
ha_rows best_quick_prefix_records= 0;
7937
uint32_t best_param_idx= 0;
8051
uint best_param_idx= 0;
7938
8052
double cur_read_cost= DBL_MAX;
7939
8053
ha_rows cur_records;
7940
8054
SEL_ARG *cur_index_tree= NULL;
7941
8055
ha_rows cur_quick_prefix_records= 0;
7942
uint32_t cur_param_idx=MAX_KEY;
8056
uint cur_param_idx=MAX_KEY;
7943
8057
key_map cur_used_key_parts;
7944
uint32_t pk= param->table->s->primary_key;
8058
uint pk= param->table->s->primary_key;
7946
for (uint32_t cur_index= 0 ; cur_index_info != cur_index_info_end ;
8060
for (uint cur_index= 0 ; cur_index_info != cur_index_info_end ;
7947
8061
cur_index_info++, cur_index++)
7949
8063
/* Check (B1) - if current index is covering. */
8589
void cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
8590
uint32_t group_key_parts, SEL_TREE *range_tree,
8591
SEL_ARG *index_tree __attribute__((unused)),
8592
ha_rows quick_prefix_records,
8711
void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
8712
uint group_key_parts, SEL_TREE *range_tree,
8713
SEL_ARG *index_tree, ha_rows quick_prefix_records,
8593
8714
bool have_min, bool have_max,
8594
8715
double *read_cost, ha_rows *records)
8596
8717
ha_rows table_records;
8597
uint32_t num_groups;
8598
uint32_t num_blocks;
8599
uint32_t keys_per_block;
8600
uint32_t keys_per_group;
8601
uint32_t keys_per_subgroup; /* Average number of keys in sub-groups */
8720
uint keys_per_block;
8721
uint keys_per_group;
8722
uint keys_per_subgroup; /* Average number of keys in sub-groups */
8602
8723
/* formed by a key infix. */
8603
8724
double p_overlap; /* Probability that a sub-group overlaps two blocks. */
8604
8725
double quick_prefix_selectivity;
8605
8726
double io_cost;
8606
8727
double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */
8728
DBUG_ENTER("cost_group_min_max");
8608
8730
table_records= table->file->stats.records;
8609
8731
keys_per_block= (table->file->stats.block_size / 2 /
8785
8912
QUICK_GROUP_MIN_MAX_SELECT::
8786
QUICK_GROUP_MIN_MAX_SELECT(Table *table, JOIN *join_arg, bool have_min_arg,
8913
QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
8787
8914
bool have_max_arg,
8788
8915
KEY_PART_INFO *min_max_arg_part_arg,
8789
uint32_t group_prefix_len_arg, uint32_t group_key_parts_arg,
8790
uint32_t used_key_parts_arg, KEY *index_info_arg,
8791
uint32_t use_index, double read_cost_arg,
8792
ha_rows records_arg, uint32_t key_infix_len_arg,
8793
unsigned char *key_infix_arg, MEM_ROOT *parent_alloc)
8916
uint group_prefix_len_arg, uint group_key_parts_arg,
8917
uint used_key_parts_arg, KEY *index_info_arg,
8918
uint use_index, double read_cost_arg,
8919
ha_rows records_arg, uint key_infix_len_arg,
8920
uchar *key_infix_arg, MEM_ROOT *parent_alloc)
8794
8921
:join(join_arg), index_info(index_info_arg),
8795
8922
group_prefix_len(group_prefix_len_arg),
8796
8923
group_key_parts(group_key_parts_arg), have_min(have_min_arg),
9780
9922
if (!tmp.length())
9781
9923
tmp.append(STRING_WITH_LEN("(empty)"));
9924
DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr()));
9929
/*****************************************************************************
9930
** Print a quick range for debugging
9932
** This should be changed to use a String to store each row instead
9933
** of locking the DEBUG stream !
9934
*****************************************************************************/
9937
print_key(KEY_PART *key_part, const uchar *key, uint used_length)
9940
const uchar *key_end= key+used_length;
9941
String tmp(buff,sizeof(buff),&my_charset_bin);
9943
TABLE *table= key_part->field->table;
9944
my_bitmap_map *old_write_set, *old_read_set;
9945
old_write_set= dbug_tmp_use_all_columns(table, table->write_set);
9946
old_read_set= dbug_tmp_use_all_columns(table, table->read_set);
9948
for (; key < key_end; key+=store_length, key_part++)
9950
Field *field= key_part->field;
9951
store_length= key_part->store_length;
9953
if (field->real_maybe_null())
9957
fwrite("NULL",sizeof(char),4,DBUG_FILE);
9960
key++; // Skip null byte
9963
field->set_key_image(key, key_part->length);
9964
field->val_str(&tmp);
9965
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
9966
if (key+store_length < key_end)
9967
fputc('/',DBUG_FILE);
9969
dbug_tmp_restore_column_map(table->write_set, old_write_set);
9970
dbug_tmp_restore_column_map(table->read_set, old_read_set);
9974
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg)
9976
char buf[MAX_KEY/8+1];
9978
my_bitmap_map *old_read_map, *old_write_map;
9979
DBUG_ENTER("print_quick");
9985
old_read_map= dbug_tmp_use_all_columns(table, table->read_set);
9986
old_write_map= dbug_tmp_use_all_columns(table, table->write_set);
9987
quick->dbug_dump(0, true);
9988
dbug_tmp_restore_column_map(table->read_set, old_read_map);
9989
dbug_tmp_restore_column_map(table->write_set, old_write_map);
9991
fprintf(DBUG_FILE,"other_keys: 0x%s:\n", needed_reg->print(buf));
9998
void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
10000
/* purecov: begin inspected */
10001
fprintf(DBUG_FILE, "%*squick range select, key %s, length: %d\n",
10002
indent, "", head->key_info[index].name, max_used_key_length);
10006
QUICK_RANGE *range;
10007
QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
10008
QUICK_RANGE **end_range= pr + ranges.elements;
10009
for (; pr != end_range; ++pr)
10011
fprintf(DBUG_FILE, "%*s", indent + 2, "");
10013
if (!(range->flag & NO_MIN_RANGE))
10015
print_key(key_parts, range->min_key, range->min_length);
10016
if (range->flag & NEAR_MIN)
10017
fputs(" < ",DBUG_FILE);
10019
fputs(" <= ",DBUG_FILE);
10021
fputs("X",DBUG_FILE);
10023
if (!(range->flag & NO_MAX_RANGE))
10025
if (range->flag & NEAR_MAX)
10026
fputs(" < ",DBUG_FILE);
10028
fputs(" <= ",DBUG_FILE);
10029
print_key(key_parts, range->max_key, range->max_length);
10031
fputs("\n",DBUG_FILE);
10037
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
10039
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
10040
QUICK_RANGE_SELECT *quick;
10041
fprintf(DBUG_FILE, "%*squick index_merge select\n", indent, "");
10042
fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
10043
while ((quick= it++))
10044
quick->dbug_dump(indent+2, verbose);
10045
if (pk_quick_select)
10047
fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
10048
pk_quick_select->dbug_dump(indent+2, verbose);
10050
fprintf(DBUG_FILE, "%*s}\n", indent, "");
10053
void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose)
10055
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
10056
QUICK_RANGE_SELECT *quick;
10057
fprintf(DBUG_FILE, "%*squick ROR-intersect select, %scovering\n",
10058
indent, "", need_to_fetch_row? "":"non-");
10059
fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
10060
while ((quick= it++))
10061
quick->dbug_dump(indent+2, verbose);
10064
fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, "");
10065
cpk_quick->dbug_dump(indent+2, verbose);
10067
fprintf(DBUG_FILE, "%*s}\n", indent, "");
10070
void QUICK_ROR_UNION_SELECT::dbug_dump(int indent, bool verbose)
10072
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
10073
QUICK_SELECT_I *quick;
10074
fprintf(DBUG_FILE, "%*squick ROR-union select\n", indent, "");
10075
fprintf(DBUG_FILE, "%*smerged scans {\n", indent, "");
10076
while ((quick= it++))
10077
quick->dbug_dump(indent+2, verbose);
10078
fprintf(DBUG_FILE, "%*s}\n", indent, "");
10083
Print quick select information to DBUG_FILE.
10086
QUICK_GROUP_MIN_MAX_SELECT::dbug_dump()
10087
indent Indentation offset
10088
verbose If true show more detailed output.
10091
Print the contents of this quick select to DBUG_FILE. The method also
10092
calls dbug_dump() for the used quick select if any.
10095
Caller is responsible for locking DBUG_FILE before this call and unlocking
10102
void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
10105
"%*squick_group_min_max_select: index %s (%d), length: %d\n",
10106
indent, "", index_info->name, index, max_used_key_length);
10107
if (key_infix_len > 0)
10109
fprintf(DBUG_FILE, "%*susing key_infix with length %d:\n",
10110
indent, "", key_infix_len);
10112
if (quick_prefix_select)
10114
fprintf(DBUG_FILE, "%*susing quick_range_select:\n", indent, "");
10115
quick_prefix_select->dbug_dump(indent + 2, verbose);
10117
if (min_max_ranges.elements > 0)
10119
fprintf(DBUG_FILE, "%*susing %d quick_ranges for MIN/MAX:\n",
10120
indent, "", min_max_ranges.elements);
10125
#endif /* NOT_USED */
9785
10127
/*****************************************************************************
9786
10128
** Instantiate templates