From bcd88c9f9e617c4a9c426cbd0902f93a486e6b81 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Wed, 5 Nov 2008 15:53:28 +0100 Subject: [PATCH] Bug#40494: MYSQL server crashes on range access with partitioning and order by Problem was that the first index read was unordered, and the next was ordered, resulting in use of uninitialized data. Solution was to use the correct variable to see if the 'next' call should be ordered or not. mysql-test/r/partition.result: Bug#40494: MYSQL server crashes on range access with partitioning and order by Added test case for the bug. mysql-test/t/partition.test: Bug#40494: MYSQL server crashes on range access with partitioning and order by Added test case for the bug. sql/ha_partition.cc: Bug#40494: MYSQL server crashes on range access with partitioning and order by Used the wrong variable to decide to continue with ordered or unordered scan. --- mysql-test/r/partition.result | 74 +++++++++++++++++++++++++++++++++++ mysql-test/t/partition.test | 29 ++++++++++++++ sql/ha_partition.cc | 2 +- 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index e76c874324e..289a24685ff 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,4 +1,78 @@ drop table if exists t1, t2; +CREATE TABLE t1 (a INT NOT NULL, KEY(a)) +PARTITION BY RANGE(a) +(PARTITION p1 VALUES LESS THAN (200), PARTITION pmax VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (2), (40), (40), (70), (60), (90), (199); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC; +a +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +a +60 +70 +90 +INSERT INTO t1 VALUES (200), (250), (210); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC; +a +60 +70 +90 +199 +200 +210 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a ASC; +a +200 +210 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC; +a +90 +70 +60 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC; +a +210 +200 +199 +90 +70 +60 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a DESC; +a +210 +200 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +a +199 +200 +210 +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +a +200 +210 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +a +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +a +199 +200 +210 +60 +70 +90 +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +a +200 +210 +DROP TABLE t1; CREATE TABLE t1 ( a INT NOT NULL, b MEDIUMINT NOT NULL, diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 83e0cde8991..e016f72e75b 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -14,6 +14,35 @@ drop table if exists t1, t2; --enable_warnings +# +# Bug#40494: Crash MYSQL server crashes on range access with partitioning +# and order by +# +CREATE TABLE t1 (a INT NOT NULL, KEY(a)) +PARTITION BY RANGE(a) +(PARTITION p1 VALUES LESS THAN (200), PARTITION pmax VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (2), (40), (40), (70), (60), (90), (199); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +INSERT INTO t1 VALUES (200), (250), (210); +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC; +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a ASC; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC; +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC; +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a DESC; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 95; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 60 AND 220; +--sorted_result +SELECT a FROM t1 WHERE a BETWEEN 200 AND 220; +DROP TABLE t1; + # # Bug35931: Index search may return duplicates # diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 14e321218ca..303a2c152fb 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4084,7 +4084,7 @@ int ha_partition::read_range_next() { DBUG_ENTER("ha_partition::read_range_next"); - if (m_ordered) + if (m_ordered_scan_ongoing) { DBUG_RETURN(handle_ordered_next(table->record[0], eq_range)); }