diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2022-01-10 16:19:03 +0300 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2022-01-26 18:43:06 +0100 |
commit | 62760af4df6144c20adb65758322a6c99679e5d8 (patch) | |
tree | 24292829caf75ccbec9a285c12f818fe9c9b0c19 | |
parent | 96bdda6c96bd0cf63077a72c594e08ce4507c006 (diff) | |
download | mariadb-git-62760af4df6144c20adb65758322a6c99679e5d8.tar.gz |
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)
-rw-r--r-- | mysql-test/main/desc_index_range.result | 10 | ||||
-rw-r--r-- | mysql-test/main/desc_index_range.test | 10 | ||||
-rw-r--r-- | sql/opt_range.cc | 9 |
3 files changed, 25 insertions, 4 deletions
diff --git a/mysql-test/main/desc_index_range.result b/mysql-test/main/desc_index_range.result index 244659e3f48..edf13010829 100644 --- a/mysql-test/main/desc_index_range.result +++ b/mysql-test/main/desc_index_range.result @@ -179,3 +179,13 @@ json_detailed(json_extract(trace, '$**.potential_group_range_indexes')) ] drop table t1; 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; diff --git a/mysql-test/main/desc_index_range.test b/mysql-test/main/desc_index_range.test index bcb9ce83318..2f3d36c8305 100644 --- a/mysql-test/main/desc_index_range.test +++ b/mysql-test/main/desc_index_range.test @@ -86,3 +86,13 @@ from information_schema.optimizer_trace; drop table t1; 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; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b0d3ff5a0ef..0094ef92ded 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -13079,24 +13079,25 @@ int QUICK_RANGE_SELECT::cmp_next(QUICK_RANGE *range_arg) key+= store_length, key_part++) { int cmp; + bool reverse= MY_TEST(key_part->flag & HA_REVERSE_SORT); store_length= key_part->store_length; if (key_part->null_bit) { if (*key) { if (!key_part->field->is_null()) - return 1; + return reverse ? 0 : 1; continue; } else if (key_part->field->is_null()) - return 0; + return reverse ? 1 : 0; key++; // Skip null byte store_length--; } if ((cmp=key_part->field->key_cmp(key, key_part->length)) < 0) - return 0; + return reverse ? 1 : 0; if (cmp > 0) - return 1; + return reverse ? 0 : 1; } return (range_arg->flag & NEAR_MAX) ? 1 : 0; // Exact match } |