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=0;
|
||||||
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
|
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
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
|
# 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 @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency;
|
||||||
set global innodb_commit_concurrency=0;
|
set global innodb_commit_concurrency=0;
|
||||||
set global innodb_commit_concurrency=@my_innodb_commit_concurrency;
|
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
|
End of 5.0 tests
|
||||||
CREATE TABLE `t2` (
|
CREATE TABLE `t2` (
|
||||||
`k` int(11) NOT NULL auto_increment,
|
`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,
|
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
|
||||||
uint used_key_parts_arg)
|
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;
|
QUICK_RANGE *r;
|
||||||
|
|
||||||
@ -8602,10 +8603,11 @@ int QUICK_SELECT_DESC::get_next()
|
|||||||
int result;
|
int result;
|
||||||
if (last_range)
|
if (last_range)
|
||||||
{ // Already read through key
|
{ // Already read through key
|
||||||
result = ((last_range->flag & EQ_RANGE)
|
result = ((last_range->flag & EQ_RANGE &&
|
||||||
? file->index_next_same(record, last_range->min_key,
|
used_key_parts <= head->key_info[index].key_parts) ?
|
||||||
last_range->min_length) :
|
file->index_next_same(record, last_range->min_key,
|
||||||
file->index_prev(record));
|
last_range->min_length) :
|
||||||
|
file->index_prev(record));
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
if (cmp_prev(*rev_it.ref()) == 0)
|
if (cmp_prev(*rev_it.ref()) == 0)
|
||||||
@ -8629,7 +8631,9 @@ int QUICK_SELECT_DESC::get_next()
|
|||||||
continue;
|
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,
|
result = file->index_read_map(record, last_range->max_key,
|
||||||
last_range->max_keypart_map,
|
last_range->max_keypart_map,
|
||||||
@ -8638,6 +8642,8 @@ int QUICK_SELECT_DESC::get_next()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(last_range->flag & NEAR_MAX ||
|
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));
|
range_reads_after_key(last_range));
|
||||||
result=file->index_read_map(record, last_range->max_key,
|
result=file->index_read_map(record, last_range->max_key,
|
||||||
last_range->max_keypart_map,
|
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)
|
void QUICK_RANGE_SELECT::add_info_string(String *str)
|
||||||
{
|
{
|
||||||
KEY *key_info= head->key_info + index;
|
KEY *key_info= head->key_info + index;
|
||||||
|
@ -686,12 +686,10 @@ public:
|
|||||||
int get_type() { return QS_TYPE_RANGE_DESC; }
|
int get_type() { return QS_TYPE_RANGE_DESC; }
|
||||||
private:
|
private:
|
||||||
bool range_reads_after_key(QUICK_RANGE *range);
|
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(); }
|
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
|
||||||
List<QUICK_RANGE> rev_ranges;
|
List<QUICK_RANGE> rev_ranges;
|
||||||
List_iterator<QUICK_RANGE> rev_it;
|
List_iterator<QUICK_RANGE> rev_it;
|
||||||
|
uint used_key_parts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -12508,6 +12508,9 @@ part_of_refkey(TABLE *table,Field *field)
|
|||||||
@note
|
@note
|
||||||
used_key_parts is set to correct key parts used if return value != 0
|
used_key_parts is set to correct key parts used if return value != 0
|
||||||
(On other cases, used_key_part may be changed)
|
(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
|
@retval
|
||||||
1 key is ok.
|
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
|
reverse=flag; // Remember if reverse
|
||||||
key_part++;
|
key_part++;
|
||||||
}
|
}
|
||||||
*used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
|
if (on_primary_key)
|
||||||
(uint) (key_part - table->key_info[idx].key_part);
|
{
|
||||||
if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
|
uint used_key_parts_secondary= table->key_info[idx].key_parts;
|
||||||
HA_READ_PREV))
|
uint used_key_parts_pk=
|
||||||
reverse= 0; // Index can't be used
|
(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);
|
DBUG_RETURN(reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user