432
432
enum { MAX_SEL_ARGS = 16000 };
435
436
SEL_ARG(SEL_ARG &);
436
438
SEL_ARG(Field *,const unsigned char *, const unsigned char *);
437
SEL_ARG(Field *field, uint8_t part, unsigned char *min_value, unsigned char *max_value,
438
uint8_t min_flag, uint8_t max_flag, uint8_t maybe_flag);
440
SEL_ARG(Field *field,
442
unsigned char *min_value,
443
unsigned char *max_value,
439
448
SEL_ARG(enum Type type_arg)
440
:min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
441
color(BLACK), type(type_arg)
443
460
inline bool is_same(SEL_ARG *arg)
445
462
if (type != arg->type || part != arg->part)
447
464
if (type != KEY_RANGE)
449
return cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0;
451
inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; }
452
inline void maybe_smaller() { maybe_flag=1; }
466
return (cmp_min_to_min(arg) == 0 && cmp_max_to_max(arg) == 0);
469
inline void merge_flags(SEL_ARG *arg)
471
maybe_flag|= arg->maybe_flag;
474
inline void maybe_smaller()
453
479
/* Return true iff it's a single-point null interval */
454
inline bool is_null_interval() { return maybe_null && max_value[0] == 1; }
455
inline int cmp_min_to_min(SEL_ARG* arg)
480
inline bool is_null_interval()
482
return (maybe_null && max_value[0] == 1);
485
inline int cmp_min_to_min(SEL_ARG *arg)
457
487
return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag);
459
inline int cmp_min_to_max(SEL_ARG* arg)
490
inline int cmp_min_to_max(SEL_ARG *arg)
461
492
return sel_cmp(field,min_value, arg->max_value, min_flag, arg->max_flag);
463
inline int cmp_max_to_max(SEL_ARG* arg)
495
inline int cmp_max_to_max(SEL_ARG *arg)
465
497
return sel_cmp(field,max_value, arg->max_value, max_flag, arg->max_flag);
467
inline int cmp_max_to_min(SEL_ARG* arg)
500
inline int cmp_max_to_min(SEL_ARG *arg)
469
502
return sel_cmp(field,max_value, arg->min_value, max_flag, arg->min_flag);
471
SEL_ARG *clone_and(SEL_ARG* arg)
505
SEL_ARG *clone_and(SEL_ARG *arg)
472
506
{ // Get overlapping range
473
unsigned char *new_min,*new_max;
474
uint8_t flag_min,flag_max;
507
unsigned char *new_min= NULL;
508
unsigned char *new_max= NULL;
475
512
if (cmp_min_to_min(arg) >= 0)
477
new_min=min_value; flag_min=min_flag;
483
521
if (cmp_max_to_max(arg) <= 0)
485
new_max=max_value; flag_max=max_flag;
489
new_max=arg->max_value; flag_max=arg->max_flag;
528
new_max= arg->max_value;
529
flag_max= arg->max_flag;
491
return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max,
492
test(maybe_flag && arg->maybe_flag));
531
return (new SEL_ARG(field,
537
test(maybe_flag && arg->maybe_flag)));
494
540
SEL_ARG *clone_first(SEL_ARG *arg)
495
541
{ // min <= X < arg->min
496
return new SEL_ARG(field,part, min_value, arg->min_value,
497
min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
498
maybe_flag | arg->maybe_flag);
542
return (new SEL_ARG(field,part,
546
arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX,
547
maybe_flag | arg->maybe_flag));
500
550
SEL_ARG *clone_last(SEL_ARG *arg)
501
551
{ // min <= X <= key_max
502
return new SEL_ARG(field, part, min_value, arg->max_value,
503
min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
552
return (new SEL_ARG(field,
558
maybe_flag | arg->maybe_flag));
505
561
SEL_ARG *clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, SEL_ARG **next);
507
bool copy_min(SEL_ARG* arg)
563
bool copy_min(SEL_ARG *arg)
508
564
{ // Get overlapping range
509
565
if (cmp_min_to_min(arg) > 0)
511
min_value=arg->min_value; min_flag=arg->min_flag;
567
min_value= arg->min_value;
568
min_flag=arg->min_flag;
512
569
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
513
(NO_MAX_RANGE | NO_MIN_RANGE))
514
return 1; // Full range
570
(NO_MAX_RANGE | NO_MIN_RANGE))
572
return 1; // Full range
516
maybe_flag|=arg->maybe_flag;
575
maybe_flag|= arg->maybe_flag;
519
bool copy_max(SEL_ARG* arg)
579
bool copy_max(SEL_ARG *arg)
520
580
{ // Get overlapping range
521
581
if (cmp_max_to_max(arg) <= 0)
523
max_value=arg->max_value; max_flag=arg->max_flag;
583
max_value= arg->max_value;
584
max_flag= arg->max_flag;
524
585
if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
525
(NO_MAX_RANGE | NO_MIN_RANGE))
526
return 1; // Full range
586
(NO_MAX_RANGE | NO_MIN_RANGE))
588
return 1; // Full range
528
maybe_flag|=arg->maybe_flag;
591
maybe_flag|= arg->maybe_flag;
532
595
void copy_min_to_min(SEL_ARG *arg)
534
min_value=arg->min_value; min_flag=arg->min_flag;
597
min_value= arg->min_value;
598
min_flag= arg->min_flag;
536
601
void copy_min_to_max(SEL_ARG *arg)
538
max_value=arg->min_value;
539
max_flag=arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
603
max_value= arg->min_value;
604
max_flag= arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
541
607
void copy_max_to_min(SEL_ARG *arg)
543
min_value=arg->max_value;
544
min_flag=arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
609
min_value= arg->max_value;
610
min_flag= arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
546
613
/* returns a number of keypart values (0 or 1) appended to the key buffer */
547
int store_min(uint32_t length, unsigned char **min_key,uint32_t min_key_flag)
614
int store_min(uint32_t length, unsigned char **min_key, uint32_t min_key_flag)
549
616
/* "(kp1 > c1) AND (kp2 OP c2) AND ..." -> (kp1 > c1) */
550
if ((!(min_flag & NO_MIN_RANGE) &&
551
!(min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
617
if ((! (min_flag & NO_MIN_RANGE) &&
618
! (min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
553
620
if (maybe_null && *min_value)
556
memset(*min_key+1, 0, length-1);
623
memset(*min_key+1, 0, length-1);
559
memcpy(*min_key,min_value,length);
627
memcpy(*min_key,min_value,length);
560
629
(*min_key)+= length;
565
635
/* returns a number of keypart values (0 or 1) appended to the key buffer */
566
636
int store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
568
if (!(max_flag & NO_MAX_RANGE) &&
569
!(max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
638
if (! (max_flag & NO_MAX_RANGE) &&
639
! (max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
571
641
if (maybe_null && *max_value)
574
memset(*max_key+1, 0, length-1);
644
memset(*max_key + 1, 0, length-1);
577
memcpy(*max_key,max_value,length);
648
memcpy(*max_key,max_value,length);
578
650
(*max_key)+= length;
602
678
int store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
604
680
SEL_ARG *key_tree= last();
605
uint32_t res=key_tree->store_max(key[key_tree->part].store_length,
606
range_key, *range_key_flag);
681
uint32_t res= key_tree->store_max(key[key_tree->part].store_length,
607
684
(*range_key_flag)|= key_tree->max_flag;
608
685
if (key_tree->next_key_part &&
609
key_tree->next_key_part->part == key_tree->part+1 &&
610
!(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
611
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
612
res+= key_tree->next_key_part->store_max_key(key, range_key,
686
key_tree->next_key_part->part == key_tree->part+1 &&
687
! (*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
688
key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
689
res+= key_tree->next_key_part->store_max_key(key,
626
705
SEL_ARG *first();
628
707
void make_root();
629
709
inline bool simple_key()
631
return !next_key_part && elements == 1;
711
return (! next_key_part && elements == 1);
633
714
void increment_use_count(long count)
635
716
if (next_key_part)
637
next_key_part->use_count+=count;
638
count*= (next_key_part->use_count-count);
639
for (SEL_ARG *pos=next_key_part->first(); pos ; pos=pos->next)
640
if (pos->next_key_part)
641
pos->increment_use_count(count);
718
next_key_part->use_count+= count;
719
count*= (next_key_part->use_count - count);
720
for (SEL_ARG *pos= next_key_part->first(); pos; pos= pos->next)
721
if (pos->next_key_part)
722
pos->increment_use_count(count);
646
for (SEL_ARG *pos=first(); pos ; pos=pos->next)
728
for (SEL_ARG *pos= first(); pos; pos= pos->next)
647
729
if (pos->next_key_part)
649
pos->next_key_part->use_count--;
650
pos->next_key_part->free_tree();
731
pos->next_key_part->use_count--;
732
pos->next_key_part->free_tree();
818
901
struct st_ror_scan_info;
820
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
821
Item_func::Functype type,Item *value,
822
Item_result cmp_type);
823
static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,COND *cond_func,Field *field,
825
Item_func::Functype type,Item *value);
903
static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,
906
Item_func::Functype type,
908
Item_result cmp_type);
910
static SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param,
911
COND *cond_func,Field *field,
913
Item_func::Functype type,Item *value);
826
915
static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond);
828
917
static bool is_key_scan_ror(PARAM *param, uint32_t keynr, uint8_t nparts);
829
919
static ha_rows check_quick_select(PARAM *param, uint32_t idx, bool index_only,
830
920
SEL_ARG *tree, bool update_tbl_stats,
831
921
uint32_t *mrr_flags, uint32_t *bufsize,
835
925
bool index_read_must_be_used,
836
926
bool update_tbl_stats,
837
927
double read_time);
839
930
TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
840
931
double read_time,
841
932
bool *are_all_covering);
843
935
TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
845
937
double read_time);
847
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
940
TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param,
848
942
double read_time);
850
945
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
852
static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
947
static void print_sel_tree(PARAM *param,
853
950
const char *msg);
854
static void print_ror_scans_arr(Table *table, const char *msg,
952
static void print_ror_scans_arr(Table *table,
855
954
struct st_ror_scan_info **start,
856
955
struct st_ror_scan_info **end);
858
957
static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
859
959
static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2);
860
961
static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2);
861
963
static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2);
862
static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2,
965
static SEL_ARG *key_and(RANGE_OPT_PARAM *param,
863
968
uint32_t clone_flag);
864
970
static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1);
866
972
static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
868
974
static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
869
static bool null_part_in_key(KEY_PART *key_part, const unsigned char *key,
976
static bool null_part_in_key(KEY_PART *key_part,
977
const unsigned char *key,
870
978
uint32_t length);
871
980
bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param);
3810
3917
return quick_imerge;
3813
optimizer::QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param,
3920
optimizer::QuickSelectInterface *TRP_ROR_INTERSECT::make_quick(PARAM *param,
3814
3921
bool retrieve_full_rows,
3815
3922
MEM_ROOT *parent_alloc)
3817
optimizer::QUICK_ROR_INTERSECT_SELECT *quick_intrsect= NULL;
3924
optimizer::QUICK_ROR_INTERSECT_SELECT *quick_intersect= NULL;
3818
3925
optimizer::QuickRangeSelect *quick= NULL;
3819
3926
MEM_ROOT *alloc= NULL;
3821
if ((quick_intrsect=
3822
new optimizer::QUICK_ROR_INTERSECT_SELECT(param->session, param->table,
3823
(retrieve_full_rows? (!is_covering) :
3928
if ((quick_intersect=
3929
new optimizer::QUICK_ROR_INTERSECT_SELECT(param->session,
3931
(retrieve_full_rows? (! is_covering) : false),
3825
3932
parent_alloc)))
3827
3934
print_ror_scans_arr(param->table,
3828
"creating ROR-intersect",
3829
first_scan, last_scan);
3830
alloc= parent_alloc? parent_alloc: &quick_intrsect->alloc;
3831
for (; first_scan != last_scan;++first_scan)
3935
"creating ROR-intersect",
3938
alloc= parent_alloc ? parent_alloc : &quick_intersect->alloc;
3939
for (; first_scan != last_scan; ++first_scan)
3833
3941
if (! (quick= optimizer::get_quick_select(param,
3834
3942
(*first_scan)->idx,
7320
7431
int optimizer::QuickRangeSelect::reset()
7323
unsigned char *mrange_buff;
7433
uint32_t buf_size= 0;
7434
unsigned char *mrange_buff= NULL;
7325
7436
HANDLER_BUFFER empty_buf;
7326
7437
last_range= NULL;
7327
7438
cur_range= (optimizer::QuickRange**) ranges.buffer;
7329
if (cursor->inited == Cursor::NONE && (error= cursor->ha_index_init(index,1)))
7440
if (cursor->inited == Cursor::NONE && (error= cursor->ha_index_init(index, 1)))
7332
7445
/* Allocate buffer if we need one but haven't allocated it yet */
7333
if (mrr_buf_size && !mrr_buf_desc)
7446
if (mrr_buf_size && ! mrr_buf_desc)
7335
7448
buf_size= mrr_buf_size;
7336
7449
while (buf_size && ! memory::multi_malloc(false,
7337
&mrr_buf_desc, sizeof(*mrr_buf_desc),
7338
&mrange_buff, buf_size,
7451
sizeof(*mrr_buf_desc),
7341
7456
/* Try to shrink the buffers until both are 0. */
7345
return(HA_ERR_OUT_OF_MEM);
7461
return HA_ERR_OUT_OF_MEM;
7347
7464
/* Initialize the Cursor buffer. */
7348
7465
mrr_buf_desc->buffer= mrange_buff;
7350
7467
mrr_buf_desc->end_of_used_area= mrange_buff;
7354
empty_buf.buffer= empty_buf.buffer_end= empty_buf.end_of_used_area= NULL;
7472
empty_buf.buffer= NULL;
7473
empty_buf.buffer_end= NULL;
7474
empty_buf.end_of_used_area= NULL;
7357
mrr_flags |= HA_MRR_SORTED;
7358
RANGE_SEQ_IF seq_funcs= {optimizer::quick_range_seq_init, optimizer::quick_range_seq_next};
7359
error= cursor->multi_range_read_init(&seq_funcs, (void*)this, ranges.elements,
7360
mrr_flags, mrr_buf_desc? mrr_buf_desc:
7479
mrr_flags|= HA_MRR_SORTED;
7481
RANGE_SEQ_IF seq_funcs= {
7482
optimizer::quick_range_seq_init,
7483
optimizer::quick_range_seq_next
7485
error= cursor->multi_range_read_init(&seq_funcs,
7489
mrr_buf_desc ? mrr_buf_desc : &empty_buf);
7400
7528
1 No more ranges in the sequence
7403
7530
uint32_t optimizer::quick_range_seq_next(range_seq_t rseq, KEY_MULTI_RANGE *range)
7405
QUICK_RANGE_SEQ_CTX *ctx= (QUICK_RANGE_SEQ_CTX*)rseq;
7532
QuickRangeSequenceContext *ctx= (QuickRangeSequenceContext*) rseq;
7407
7534
if (ctx->cur == ctx->last)
7408
7535
return 1; /* no more ranges */
7410
7537
optimizer::QuickRange *cur= *(ctx->cur);
7411
7538
key_range *start_key= &range->start_key;
7412
key_range *end_key= &range->end_key;
7539
key_range *end_key= &range->end_key;
7414
start_key->key= cur->min_key;
7541
start_key->key= cur->min_key;
7415
7542
start_key->length= cur->min_length;
7416
7543
start_key->keypart_map= cur->min_keypart_map;
7417
start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7418
(cur->flag & EQ_RANGE) ?
7419
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7420
end_key->key= cur->max_key;
7421
end_key->length= cur->max_length;
7544
start_key->flag= ((cur->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7545
(cur->flag & EQ_RANGE) ?
7546
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7547
end_key->key= cur->max_key;
7548
end_key->length= cur->max_length;
7422
7549
end_key->keypart_map= cur->max_keypart_map;
7424
7551
We use HA_READ_AFTER_KEY here because if we are reading on a key
7425
7552
prefix. We want to find all keys with this prefix.
7427
end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7554
end_key->flag= (cur->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7429
7556
range->range_flag= cur->flag;
7526
7653
last_range= *(cur_range++);
7528
start_key.key= (const unsigned char*) last_range->min_key;
7655
start_key.key= (const unsigned char*) last_range->min_key;
7529
7656
start_key.length= min(last_range->min_length, (uint16_t)prefix_length);
7530
7657
start_key.keypart_map= last_range->min_keypart_map & keypart_map;
7531
start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7532
(last_range->flag & EQ_RANGE) ?
7533
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7534
end_key.key= (const unsigned char*) last_range->max_key;
7535
end_key.length= min(last_range->max_length, (uint16_t)prefix_length);
7658
start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
7659
(last_range->flag & EQ_RANGE) ?
7660
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
7661
end_key.key= (const unsigned char*) last_range->max_key;
7662
end_key.length= min(last_range->max_length, (uint16_t)prefix_length);
7536
7663
end_key.keypart_map= last_range->max_keypart_map & keypart_map;
7538
7665
We use READ_AFTER_KEY here because if we are reading on a key
7539
7666
prefix we want to find all keys with this prefix
7541
end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7668
end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
7544
7671
result= cursor->read_range_first(last_range->min_keypart_map ? &start_key : 0,
7545
last_range->max_keypart_map ? &end_key : 0,
7546
test(last_range->flag & EQ_RANGE),
7672
last_range->max_keypart_map ? &end_key : 0,
7673
test(last_range->flag & EQ_RANGE),
7548
7675
if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7549
last_range= 0; // Stop searching
7676
last_range= 0; // Stop searching
7551
7678
if (result != HA_ERR_END_OF_FILE)
7553
last_range= 0; // No matching rows; go to next range
7680
last_range= 0; // No matching rows; go to next range
7642
7767
* - otherwise (not NEAR_MAX == include the key), go after the key,
7643
7768
* step back once, and move backwards
7649
7773
if (last_range)
7650
7774
{ // Already read through key
7651
result = ((last_range->flag & EQ_RANGE)
7652
? cursor->index_next_same(record, last_range->min_key,
7653
last_range->min_length) :
7654
cursor->index_prev(record));
7775
result= ((last_range->flag & EQ_RANGE) ?
7776
cursor->index_next_same(record, last_range->min_key,
7777
last_range->min_length) :
7778
cursor->index_prev(record));
7657
if (cmp_prev(*rev_it.ref()) == 0)
7781
if (cmp_prev(*rev_it.ref()) == 0)
7660
7784
else if (result != HA_ERR_END_OF_FILE)
7664
if (!(last_range= rev_it++))
7788
if (! (last_range= rev_it++))
7665
7789
return HA_ERR_END_OF_FILE; // All ranges used
7667
7791
if (last_range->flag & NO_MAX_RANGE) // Read last record
7669
7793
int local_error;
7670
if ((local_error=cursor->index_last(record)))
7671
return(local_error); // Empty table
7794
if ((local_error= cursor->index_last(record)))
7795
return local_error; // Empty table
7672
7796
if (cmp_prev(last_range) == 0)
7674
last_range= 0; // No match; go to next range
7798
last_range= 0; // No match; go to next range
7678
7802
if (last_range->flag & EQ_RANGE)
7680
result = cursor->index_read_map(record, last_range->max_key,
7681
last_range->max_keypart_map,
7804
result = cursor->index_read_map(record,
7805
last_range->max_key,
7806
last_range->max_keypart_map,
7686
7811
assert(last_range->flag & NEAR_MAX ||
7687
range_reads_after_key(last_range));
7688
result=cursor->index_read_map(record, last_range->max_key,
7689
last_range->max_keypart_map,
7690
((last_range->flag & NEAR_MAX) ?
7691
HA_READ_BEFORE_KEY :
7692
HA_READ_PREFIX_LAST_OR_PREV));
7812
range_reads_after_key(last_range));
7813
result= cursor->index_read_map(record,
7814
last_range->max_key,
7815
last_range->max_keypart_map,
7816
((last_range->flag & NEAR_MAX) ?
7817
HA_READ_BEFORE_KEY :
7818
HA_READ_PREFIX_LAST_OR_PREV));
7696
7822
if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
7698
7824
last_range= 0; // Not found, to next range
7701
7827
if (cmp_prev(last_range) == 0)
7703
7829
if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
7704
last_range= 0; // Stop searching
7830
last_range= 0; // Stop searching
7705
7831
return 0; // Found key is in range
7707
7833
last_range= 0; // To next range
7957
8087
*******************************************************************************/
7959
8089
static inline uint32_t get_field_keypart(KEY *index, Field *field);
7960
static inline SEL_ARG * get_index_range_tree(uint32_t index, SEL_TREE* range_tree,
7961
PARAM *param, uint32_t *param_idx);
7962
static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
7963
KEY_PART_INFO *first_non_group_part,
7964
KEY_PART_INFO *min_max_arg_part,
7965
KEY_PART_INFO *last_part, Session *session,
7966
unsigned char *key_infix, uint32_t *key_infix_len,
7967
KEY_PART_INFO **first_non_infix_part);
8091
static inline SEL_ARG * get_index_range_tree(uint32_t index,
8092
SEL_TREE* range_tree,
8094
uint32_t *param_idx);
8096
static bool get_constant_key_infix(KEY *index_info,
8097
SEL_ARG *index_range_tree,
8098
KEY_PART_INFO *first_non_group_part,
8099
KEY_PART_INFO *min_max_arg_part,
8100
KEY_PART_INFO *last_part,
8102
unsigned char *key_infix,
8103
uint32_t *key_infix_len,
8104
KEY_PART_INFO **first_non_infix_part);
7968
8106
static bool check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item);
7971
cost_group_min_max(Table* table, KEY *index_info, uint32_t used_key_parts,
7972
uint32_t group_key_parts, SEL_TREE *range_tree,
7973
SEL_ARG *index_tree, ha_rows quick_prefix_records,
7974
bool have_min, bool have_max,
7975
double *read_cost, ha_rows *records);
8109
cost_group_min_max(Table* table,
8111
uint32_t used_key_parts,
8112
uint32_t group_key_parts,
8113
SEL_TREE *range_tree,
8114
SEL_ARG *index_tree,
8115
ha_rows quick_prefix_records,
8365
8513
if (first_non_group_part &&
8366
(!min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
8514
(! min_max_arg_part || (min_max_arg_part - first_non_group_part > 0)))
8370
8518
uint32_t dummy;
8371
SEL_ARG *index_range_tree= get_index_range_tree(cur_index, tree, param,
8519
SEL_ARG *index_range_tree= get_index_range_tree(cur_index,
8373
if (!get_constant_key_infix(cur_index_info, index_range_tree,
8374
first_non_group_part, min_max_arg_part,
8375
last_part, session, cur_key_infix,
8377
&first_non_infix_part))
8523
if (! get_constant_key_infix(cur_index_info,
8525
first_non_group_part,
8531
&first_non_infix_part))
8378
8533
goto next_index;
8380
8536
else if (min_max_arg_part &&
8381
8537
(min_max_arg_part - first_non_group_part > 0))
8437
8594
/* Find the SEL_ARG sub-tree that corresponds to the chosen index. */
8438
cur_index_tree= get_index_range_tree(cur_index, tree, param,
8595
cur_index_tree= get_index_range_tree(cur_index,
8439
8598
&cur_param_idx);
8440
8599
/* Check if this range tree can be used for prefix retrieval. */
8441
8600
COST_VECT dummy_cost;
8442
8601
uint32_t mrr_flags= HA_MRR_USE_DEFAULT_IMPL;
8443
uint32_t mrr_bufsize=0;
8444
cur_quick_prefix_records= check_quick_select(param, cur_param_idx,
8602
uint32_t mrr_bufsize= 0;
8603
cur_quick_prefix_records= check_quick_select(param,
8445
8605
false /*don't care*/,
8446
cur_index_tree, true,
8447
&mrr_flags, &mrr_bufsize,
8450
cost_group_min_max(table, cur_index_info, cur_used_key_parts,
8451
cur_group_key_parts, tree, cur_index_tree,
8452
cur_quick_prefix_records, have_min, have_max,
8453
&cur_read_cost, &cur_records);
8612
cost_group_min_max(table,
8615
cur_group_key_parts,
8618
cur_quick_prefix_records,
8455
8624
If cur_read_cost is lower than best_read_cost use cur_index.
8456
8625
Do not compare doubles directly because they may have different
8490
8663
/* The query passes all tests, so construct a new TRP object. */
8491
read_plan= new (param->mem_root)
8492
TRP_GROUP_MIN_MAX(have_min, have_max, min_max_arg_part,
8493
group_prefix_len, used_key_parts,
8494
group_key_parts, index_info, index,
8496
(key_infix_len > 0) ? key_infix : NULL,
8497
tree, best_index_tree, best_param_idx,
8498
best_quick_prefix_records);
8665
new(param->mem_root) TRP_GROUP_MIN_MAX(have_min,
8674
(key_infix_len > 0) ? key_infix : NULL,
8678
best_quick_prefix_records);
8501
8681
if (tree && read_plan->quick_prefix_records == 0)
8504
8684
read_plan->read_cost= best_read_cost;
8505
read_plan->records= best_records;
8685
read_plan->records= best_records;
8508
8688
return read_plan;
9090
9278
join(join_arg),
9091
9279
index_info(index_info_arg),
9092
group_prefix_len(group_prefix_len_arg),
9093
group_key_parts(group_key_parts_arg),
9094
have_min(have_min_arg),
9095
have_max(have_max_arg),
9096
seen_first_key(false),
9097
min_max_arg_part(min_max_arg_part_arg),
9098
key_infix(key_infix_arg),
9099
key_infix_len(key_infix_len_arg),
9100
min_functions_it(NULL),
9101
max_functions_it(NULL)
9280
group_prefix_len(group_prefix_len_arg),
9281
group_key_parts(group_key_parts_arg),
9282
have_min(have_min_arg),
9283
have_max(have_max_arg),
9284
seen_first_key(false),
9285
min_max_arg_part(min_max_arg_part_arg),
9286
key_infix(key_infix_arg),
9287
key_infix_len(key_infix_len_arg),
9288
min_functions_it(NULL),
9289
max_functions_it(NULL)
9104
cursor= head->cursor;
9106
record= head->record[0];
9292
cursor= head->cursor;
9294
record= head->record[0];
9107
9295
tmp_record= head->record[1];
9108
9296
read_time= read_cost_arg;
9109
9297
records= records_arg;