mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-27426 Wrong result upon query using index_merge with DESC key
Make QUICK_RANGE_SELECT::cmp_next() aware of reverse-ordered key parts. (QUICK_RANGE_SELECT::cmp_prev() uses key_cmp() and so it already works correctly)
This commit is contained in:
committed by
Sergei Golubchik
parent
96bdda6c96
commit
62760af4df
@@ -179,3 +179,13 @@ json_detailed(json_extract(trace, '$**.potential_group_range_indexes'))
|
|||||||
]
|
]
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set optimizer_trace=default;
|
set optimizer_trace=default;
|
||||||
|
#
|
||||||
|
# MDEV-27426: Wrong result upon query using index_merge with DESC key
|
||||||
|
#
|
||||||
|
CREATE OR REPLACE TABLE t1 (pk INT, a INT, b int, KEY(a), PRIMARY KEY(pk DESC)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1,4,5),(2,9,6),(3,NULL,7),(4,NULL,8);
|
||||||
|
SELECT * FROM t1 WHERE pk > 10 OR a > 0;
|
||||||
|
pk a b
|
||||||
|
1 4 5
|
||||||
|
2 9 6
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -86,3 +86,13 @@ from information_schema.optimizer_trace;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
set optimizer_trace=default;
|
set optimizer_trace=default;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27426: Wrong result upon query using index_merge with DESC key
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE OR REPLACE TABLE t1 (pk INT, a INT, b int, KEY(a), PRIMARY KEY(pk DESC)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1,4,5),(2,9,6),(3,NULL,7),(4,NULL,8);
|
||||||
|
|
||||||
|
SELECT * FROM t1 WHERE pk > 10 OR a > 0;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -13079,24 +13079,25 @@ int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
|
|||||||
key+= store_length, key_part++)
|
key+= store_length, key_part++)
|
||||||
{
|
{
|
||||||
int cmp;
|
int cmp;
|
||||||
|
bool reverse= MY_TEST(key_part->flag & HA_REVERSE_SORT);
|
||||||
store_length= key_part->store_length;
|
store_length= key_part->store_length;
|
||||||
if (key_part->null_bit)
|
if (key_part->null_bit)
|
||||||
{
|
{
|
||||||
if (*key)
|
if (*key)
|
||||||
{
|
{
|
||||||
if (!key_part->field->is_null())
|
if (!key_part->field->is_null())
|
||||||
return 1;
|
return reverse ? 0 : 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (key_part->field->is_null())
|
else if (key_part->field->is_null())
|
||||||
return 0;
|
return reverse ? 1 : 0;
|
||||||
key++; // Skip null byte
|
key++; // Skip null byte
|
||||||
store_length--;
|
store_length--;
|
||||||
}
|
}
|
||||||
if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
|
if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
|
||||||
return 0;
|
return reverse ? 1 : 0;
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
return 1;
|
return reverse ? 0 : 1;
|
||||||
}
|
}
|
||||||
return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
|
return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user