Skip to content

Commit 62760af

Browse files
spetruniavuvova
authored andcommitted
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)
1 parent 96bdda6 commit 62760af

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

mysql-test/main/desc_index_range.result

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,13 @@ json_detailed(json_extract(trace, '$**.potential_group_range_indexes'))
179179
]
180180
drop table t1;
181181
set optimizer_trace=default;
182+
#
183+
# MDEV-27426: Wrong result upon query using index_merge with DESC key
184+
#
185+
CREATE OR REPLACE TABLE t1 (pk INT, a INT, b int, KEY(a), PRIMARY KEY(pk DESC)) ENGINE=InnoDB;
186+
INSERT INTO t1 VALUES (1,4,5),(2,9,6),(3,NULL,7),(4,NULL,8);
187+
SELECT * FROM t1 WHERE pk > 10 OR a > 0;
188+
pk a b
189+
1 4 5
190+
2 9 6
191+
DROP TABLE t1;

mysql-test/main/desc_index_range.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,13 @@ from information_schema.optimizer_trace;
8686
drop table t1;
8787

8888
set optimizer_trace=default;
89+
90+
--echo #
91+
--echo # MDEV-27426: Wrong result upon query using index_merge with DESC key
92+
--echo #
93+
94+
CREATE OR REPLACE TABLE t1 (pk INT, a INT, b int, KEY(a), PRIMARY KEY(pk DESC)) ENGINE=InnoDB;
95+
INSERT INTO t1 VALUES (1,4,5),(2,9,6),(3,NULL,7),(4,NULL,8);
96+
97+
SELECT * FROM t1 WHERE pk > 10 OR a > 0;
98+
DROP TABLE t1;

sql/opt_range.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13079,24 +13079,25 @@ int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg)
1307913079
key+= store_length, key_part++)
1308013080
{
1308113081
int cmp;
13082+
bool reverse= MY_TEST(key_part->flag & HA_REVERSE_SORT);
1308213083
store_length= key_part->store_length;
1308313084
if (key_part->null_bit)
1308413085
{
1308513086
if (*key)
1308613087
{
1308713088
if (!key_part->field->is_null())
13088-
return 1;
13089+
return reverse ? 0 : 1;
1308913090
continue;
1309013091
}
1309113092
else if (key_part->field->is_null())
13092-
return 0;
13093+
return reverse ? 1 : 0;
1309313094
key++; // Skip null byte
1309413095
store_length--;
1309513096
}
1309613097
if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0)
13097-
return 0;
13098+
return reverse ? 1 : 0;
1309813099
if (cmp > 0)
13099-
return 1;
13100+
return reverse ? 0 : 1;
1310013101
}
1310113102
return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match
1310213103
}

0 commit comments

Comments
 (0)