1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Bug#37830 : ORDER BY ASC/DESC - no difference

Range scan in descending order for c <= <col> <= c type of
ranges was ignoring the DESC flag.
However some engines like InnoDB have the primary key parts 
as a suffix for every secondary key.
When such primary key suffix is used for ordering ignoring 
the DESC is not valid.
But we generally would like to do this because it's faster.
      
Fixed by performing only reverse scan if the primary key is used.
Removed some dead code in the process.
This commit is contained in:
Georgi Kodinov
2008-07-16 12:31:50 +03:00
parent 52f510ef22
commit 59ab9a0872
5 changed files with 83 additions and 79 deletions

View File

@ -7094,7 +7094,8 @@ bool QUICK_RANGE_SELECT::row_in_ranges()
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
uint used_key_parts_arg)
: QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
: QUICK_RANGE_SELECT(*q), rev_it(rev_ranges),
used_key_parts (used_key_parts_arg)
{
QUICK_RANGE *r;
@ -7136,10 +7137,11 @@ int QUICK_SELECT_DESC::get_next()
int result;
if (last_range)
{ // Already read through key
result = ((last_range->flag & EQ_RANGE)
? file->index_next_same(record, (byte*) last_range->min_key,
last_range->min_length) :
file->index_prev(record));
result = ((last_range->flag & EQ_RANGE &&
used_key_parts <= head->key_info[index].key_parts) ?
file->index_next_same(record, (byte*) last_range->min_key,
last_range->min_length) :
file->index_prev(record));
if (!result)
{
if (cmp_prev(*rev_it.ref()) == 0)
@ -7163,7 +7165,9 @@ int QUICK_SELECT_DESC::get_next()
continue;
}
if (last_range->flag & EQ_RANGE)
if (last_range->flag & EQ_RANGE &&
used_key_parts <= head->key_info[index].key_parts)
{
result= file->index_read(record, (byte*) last_range->max_key,
last_range->max_length, HA_READ_KEY_EXACT);
@ -7171,6 +7175,8 @@ int QUICK_SELECT_DESC::get_next()
else
{
DBUG_ASSERT(last_range->flag & NEAR_MAX ||
(last_range->flag & EQ_RANGE &&
used_key_parts > head->key_info[index].key_parts) ||
range_reads_after_key(last_range));
result=file->index_read(record, (byte*) last_range->max_key,
last_range->max_length,
@ -7268,54 +7274,6 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg)
}
/* TRUE if we are reading over a key that may have a NULL value */
#ifdef NOT_USED
bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
uint used_key_parts)
{
uint offset, end;
KEY_PART *key_part = key_parts,
*key_part_end= key_part+used_key_parts;
for (offset= 0, end = min(range_arg->min_length, range_arg->max_length) ;
offset < end && key_part != key_part_end ;
offset+= key_part++->store_length)
{
if (!memcmp((char*) range_arg->min_key+offset,
(char*) range_arg->max_key+offset,
key_part->store_length))
continue;
if (key_part->null_bit && range_arg->min_key[offset])
return 1; // min_key is null and max_key isn't
// Range doesn't cover NULL. This is ok if there is no more null parts
break;
}
/*
If the next min_range is > NULL, then we can use this, even if
it's a NULL key
Example: SELECT * FROM t1 WHERE a = 2 AND b >0 ORDER BY a DESC,b DESC;
*/
if (key_part != key_part_end && key_part->null_bit)
{
if (offset >= range_arg->min_length || range_arg->min_key[offset])
return 1; // Could be null
key_part++;
}
/*
If any of the key parts used in the ORDER BY could be NULL, we can't
use the key to sort the data.
*/
for (; key_part != key_part_end ; key_part++)
if (key_part->null_bit)
return 1; // Covers null part
return 0;
}
#endif
void QUICK_RANGE_SELECT::add_info_string(String *str)
{
KEY *key_info= head->key_info + index;