mirror of
https://github.com/MariaDB/server.git
synced 2025-05-02 19:25:03 +03:00
Automerge
This commit is contained in:
commit
19e2ed7642
@ -1103,6 +1103,24 @@ set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
|
||||
set global innodb_commit_concurrency=0;
|
||||
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
|
||||
|
||||
#
|
||||
# Bug #37830: ORDER BY ASC/DESC - no difference
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
|
||||
ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
|
||||
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
|
||||
|
||||
# should be range access
|
||||
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
|
||||
|
||||
# should produce '8 7 6 5 4' for a
|
||||
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
||||
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
|
||||
|
@ -1362,6 +1362,21 @@ set global innodb_autoextend_increment=@my_innodb_autoextend_increment;
|
||||
set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
|
||||
set global innodb_commit_concurrency=0;
|
||||
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
|
||||
CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
|
||||
ENGINE=InnoDB;
|
||||
INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
|
||||
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
|
||||
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index t1_b PRIMARY 4 NULL 8 Using where
|
||||
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
|
||||
a b c
|
||||
8 1 1
|
||||
7 1 1
|
||||
6 1 1
|
||||
5 1 1
|
||||
4 1 1
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
CREATE TABLE `t2` (
|
||||
`k` int(11) NOT NULL auto_increment,
|
||||
|
@ -8560,7 +8560,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;
|
||||
|
||||
@ -8602,10 +8603,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, 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, last_range->min_key,
|
||||
last_range->min_length) :
|
||||
file->index_prev(record));
|
||||
if (!result)
|
||||
{
|
||||
if (cmp_prev(*rev_it.ref()) == 0)
|
||||
@ -8629,7 +8631,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_map(record, last_range->max_key,
|
||||
last_range->max_keypart_map,
|
||||
@ -8638,6 +8642,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_map(record, last_range->max_key,
|
||||
last_range->max_keypart_map,
|
||||
@ -8735,54 +8741,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;
|
||||
|
@ -686,12 +686,10 @@ public:
|
||||
int get_type() { return QS_TYPE_RANGE_DESC; }
|
||||
private:
|
||||
bool range_reads_after_key(QUICK_RANGE *range);
|
||||
#ifdef NOT_USED
|
||||
bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
|
||||
#endif
|
||||
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
|
||||
List<QUICK_RANGE> rev_ranges;
|
||||
List_iterator<QUICK_RANGE> rev_it;
|
||||
uint used_key_parts;
|
||||
};
|
||||
|
||||
|
||||
|
@ -12508,6 +12508,9 @@ part_of_refkey(TABLE *table,Field *field)
|
||||
@note
|
||||
used_key_parts is set to correct key parts used if return value != 0
|
||||
(On other cases, used_key_part may be changed)
|
||||
Note that the value may actually be greater than the number of index
|
||||
key parts. This can happen for storage engines that have the primary
|
||||
key parts as a suffix for every secondary key.
|
||||
|
||||
@retval
|
||||
1 key is ok.
|
||||
@ -12580,11 +12583,27 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
reverse=flag; // Remember if reverse
|
||||
key_part++;
|
||||
}
|
||||
*used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
|
||||
(uint) (key_part - table->key_info[idx].key_part);
|
||||
if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
|
||||
HA_READ_PREV))
|
||||
reverse= 0; // Index can't be used
|
||||
if (on_primary_key)
|
||||
{
|
||||
uint used_key_parts_secondary= table->key_info[idx].key_parts;
|
||||
uint used_key_parts_pk=
|
||||
(uint) (key_part - table->key_info[table->s->primary_key].key_part);
|
||||
*used_key_parts= used_key_parts_pk + used_key_parts_secondary;
|
||||
|
||||
if (reverse == -1 &&
|
||||
(!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
|
||||
HA_READ_PREV) ||
|
||||
!(table->file->index_flags(table->s->primary_key,
|
||||
used_key_parts_pk - 1, 1) & HA_READ_PREV)))
|
||||
reverse= 0; // Index can't be used
|
||||
}
|
||||
else
|
||||
{
|
||||
*used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
|
||||
if (reverse == -1 &&
|
||||
!(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
|
||||
reverse= 0; // Index can't be used
|
||||
}
|
||||
DBUG_RETURN(reverse);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user