mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-38649: Wrong result for range w/o min endpoint, ORDER BY DESC
QUICK_SELECT_DESC::get_next() sets a stale end range on the storage engine. When checking the first range, it sets last_range to the first range and then, if it cannot avoid descending scan, it sets the minimum endpoint on the storage engine. However, get_next() may decide that this range is not a match after updating the minimum endpoint on the storage engine. In this case, it will continue to the next range. When continuing, it needs to reset not only the state of 'last_range' to point to the next range that it's checking, but it also needs to clear the now-stale end range set on the storage engine. While this explanation covers the first and second ranges, the issue at hand extends to the general case of ranges 1...N-1 and N. Before this change and when get_next() decided that a range was not a match, it would clear last_range at each loop continuation point. Rather than clearing the minimum endpoint on the storage engine at each continuation, we move all loop cleanup to for loop update clause. This consolidates any logic that needs to be evaluated on loop continuation to one place and reduces code duplication. MySQL fixed this same problem at sha b65ca959efd6ec5369165b1849407318b4886634 with a different implementation.
This commit is contained in:
committed by
Dave Gosselin
parent
768b6a2052
commit
bbcd7defbb
@@ -4849,4 +4849,23 @@ ERROR 42S22: Unknown column '-5' in 'ORDER BY'
|
||||
SELECT 1 FROM (select 1) dt order BY 50;
|
||||
ERROR 42S22: Unknown column '50' in 'ORDER BY'
|
||||
# End of 10.11 tests
|
||||
#
|
||||
# MDEV-38649: Wrong result (missing rows) upon condition pushdown on table with DESC key
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT not null, KEY(b));
|
||||
INSERT INTO t1 VALUES (2,8),(9,1),(4,6);
|
||||
SELECT a, b FROM t1 WHERE b != 10 and b < 30 ORDER BY b DESC;
|
||||
a b
|
||||
2 8
|
||||
4 6
|
||||
9 1
|
||||
SELECT a, b FROM t1 use index() WHERE b != 10 and b < 30 ORDER BY b DESC;
|
||||
a b
|
||||
2 8
|
||||
4 6
|
||||
9 1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 12.3 tests
|
||||
#
|
||||
ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci;
|
||||
|
||||
@@ -2831,4 +2831,17 @@ SELECT 1 FROM (select 1) dt order BY 50;
|
||||
|
||||
--echo # End of 10.11 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-38649: Wrong result (missing rows) upon condition pushdown on table with DESC key
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT, b INT not null, KEY(b));
|
||||
INSERT INTO t1 VALUES (2,8),(9,1),(4,6);
|
||||
SELECT a, b FROM t1 WHERE b != 10 and b < 30 ORDER BY b DESC;
|
||||
SELECT a, b FROM t1 use index() WHERE b != 10 and b < 30 ORDER BY b DESC;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 12.3 tests
|
||||
--echo #
|
||||
|
||||
--source include/test_db_charset_restore.inc
|
||||
|
||||
@@ -13912,7 +13912,7 @@ int QUICK_SELECT_DESC::get_next()
|
||||
* step back once, and move backwards
|
||||
*/
|
||||
|
||||
for (;;)
|
||||
for (;; last_range= nullptr, file->set_end_range(nullptr))
|
||||
{
|
||||
int result;
|
||||
if (last_range)
|
||||
@@ -13961,7 +13961,7 @@ int QUICK_SELECT_DESC::get_next()
|
||||
DBUG_RETURN(local_error); // Empty table
|
||||
if (cmp_prev(last_range) == 0)
|
||||
DBUG_RETURN(0);
|
||||
last_range= 0; // No match; go to next range
|
||||
// No match; go to next range
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -13997,7 +13997,7 @@ int QUICK_SELECT_DESC::get_next()
|
||||
{
|
||||
if (result != HA_ERR_KEY_NOT_FOUND && result != HA_ERR_END_OF_FILE)
|
||||
DBUG_RETURN(result);
|
||||
last_range= 0; // Not found, to next range
|
||||
// Not found, to next range
|
||||
continue;
|
||||
}
|
||||
if (cmp_prev(last_range) == 0)
|
||||
@@ -14006,7 +14006,7 @@ int QUICK_SELECT_DESC::get_next()
|
||||
last_range= 0; // Stop searching
|
||||
DBUG_RETURN(0); // Found key is in range
|
||||
}
|
||||
last_range= 0; // To next range
|
||||
// To next range
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user