8573
8571
mrange_slot < mrange_end;
8576
start_key= &mrange_slot->start_key;
8577
end_key= &mrange_slot->end_key;
8578
8574
last_range= *(cur_range++);
8580
start_key->key= (const uchar*) last_range->min_key;
8581
start_key->length= last_range->min_length;
8582
start_key->flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
8583
(last_range->flag & EQ_RANGE) ?
8584
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
8585
start_key->keypart_map= last_range->min_keypart_map;
8586
end_key->key= (const uchar*) last_range->max_key;
8587
end_key->length= last_range->max_length;
8589
We use HA_READ_AFTER_KEY here because if we are reading on a key
8590
prefix. We want to find all keys with this prefix.
8592
end_key->flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
8594
end_key->keypart_map= last_range->max_keypart_map;
8575
last_range->make_min_endpoint(&mrange_slot->start_key);
8576
last_range->make_max_endpoint(&mrange_slot->end_key);
8596
8577
mrange_slot->range_flag= last_range->flag;
8617
8598
Get the next record with a different prefix.
8620
QUICK_RANGE_SELECT::get_next_prefix()
8621
prefix_length length of cur_prefix
8622
cur_prefix prefix of a key to be searched for
8625
Each subsequent call to the method retrieves the first record that has a
8626
prefix with length prefix_length different from cur_prefix, such that the
8627
record with the new prefix is within the ranges described by
8628
this->ranges. The record found is stored into the buffer pointed by
8630
The method is useful for GROUP-BY queries with range conditions to
8631
discover the prefix of the next group that satisfies the range conditions.
8600
@param prefix_length length of cur_prefix
8601
@param group_key_parts The number of key parts in the group prefix
8602
@param cur_prefix prefix of a key to be searched for
8604
Each subsequent call to the method retrieves the first record that has a
8605
prefix with length prefix_length and which is different from cur_prefix,
8606
such that the record with the new prefix is within the ranges described by
8607
this->ranges. The record found is stored into the buffer pointed by
8608
this->record. The method is useful for GROUP-BY queries with range
8609
conditions to discover the prefix of the next group that satisfies the range
8634
8614
This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
8635
8615
methods should be unified into a more general one to reduce code
8640
HA_ERR_END_OF_FILE if returned all keys
8641
other if some error occurred
8618
@retval 0 on success
8619
@retval HA_ERR_END_OF_FILE if returned all keys
8620
@retval other if some error occurred
8644
8623
int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
8645
key_part_map keypart_map,
8624
uint group_key_parts,
8646
8625
uchar *cur_prefix)
8648
8627
DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
8628
const key_part_map keypart_map= make_prev_keypart_map(group_key_parts);
8653
key_range start_key, end_key;
8654
8633
if (last_range)
8656
8635
/* Read the next record in the same range with prefix after cur_prefix. */
8657
DBUG_ASSERT(cur_prefix != 0);
8636
DBUG_ASSERT(cur_prefix != NULL);
8658
8637
result= file->index_read_map(record, cur_prefix, keypart_map,
8659
8638
HA_READ_AFTER_KEY);
8660
if (result || (file->compare_key(file->end_range) <= 0))
8639
if (result || last_range->max_keypart_map == 0)
8661
8640
DBUG_RETURN(result);
8642
key_range previous_endpoint;
8643
last_range->make_max_endpoint(&previous_endpoint, prefix_length, keypart_map);
8644
if (file->compare_key(&previous_endpoint) <= 0)
8664
8648
uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
8671
8655
last_range= *(cur_range++);
8673
start_key.key= (const uchar*) last_range->min_key;
8674
start_key.length= min(last_range->min_length, prefix_length);
8675
start_key.keypart_map= last_range->min_keypart_map & keypart_map;
8676
start_key.flag= ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
8677
(last_range->flag & EQ_RANGE) ?
8678
HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
8679
end_key.key= (const uchar*) last_range->max_key;
8680
end_key.length= min(last_range->max_length, prefix_length);
8681
end_key.keypart_map= last_range->max_keypart_map & keypart_map;
8683
We use READ_AFTER_KEY here because if we are reading on a key
8684
prefix we want to find all keys with this prefix
8686
end_key.flag= (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
8657
key_range start_key, end_key;
8658
last_range->make_min_endpoint(&start_key, prefix_length, keypart_map);
8659
last_range->make_max_endpoint(&end_key, prefix_length, keypart_map);
8689
8661
result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0,
8690
8662
last_range->max_keypart_map ? &end_key : 0,
8782
This is a hack: we inherit from QUICK_SELECT so that we can use the
8754
This is a hack: we inherit from QUICK_RANGE_SELECT so that we can use the
8783
8755
get_next() interface, but we have to hold a pointer to the original
8784
QUICK_SELECT because its data are used all over the place. What
8756
QUICK_RANGE_SELECT because its data are used all over the place. What
8785
8757
should be done is to factor out the data that is needed into a base
8786
8758
class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
8787
8759
which handle the ranges and implement the get_next() function. But