summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2022-01-10 16:19:03 +0300
committerSergei Golubchik <serg@mariadb.org>2022-01-26 18:43:06 +0100
commit62760af4df6144c20adb65758322a6c99679e5d8 (patch)
tree24292829caf75ccbec9a285c12f818fe9c9b0c19
parent96bdda6c96bd0cf63077a72c594e08ce4507c006 (diff)
downloadmariadb-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.result10
-rw-r--r--mysql-test/main/desc_index_range.test10
-rw-r--r--sql/opt_range.cc9
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
}