#At file:///home/lb200670/devel/mysql/bugfest/ based on revid:svoj@stripped
3054 lars-erik.bjork@stripped 2009-03-06
This is a patch for bug#43452 Wrong number of rows returned when using LIMIT
In a transient period, we have both the old and the new values available when walking the
index. The order they are traversed is the following: (notation (recNumber,
indexValue) )
(1,1) (0,3) (1,3) (0,8)
We check the first value in IndexWalker::getValidatedRecord and see that the index value
(1) does not match the record value (3), therefore we skip it. At the next iteration we
check the next entry. We check that this is not the same record as the on the last
iteration by comparing the record number to a variable called lastRecordNumber. This value
is initialized to 0, and has not yet been updated because we skipped the previous entry.
Therefore we mistakingly think we have processed this record already and skip it. We
therefore loose the first record in the table.
The solution to this is not to initialize lastRecordNumber to 0, which is a legal record
number, but to initialize it to a negative, illegal record number.
Added file 'mysql-test/suite/falcon/t/falcon_bug_43452.test'
------------------------------------------------------------
A test testing the patch
Added file 'mysql-test/suite/falcon/r/falcon_bug_43452.result'
-------------------------------------------------------------
Expected result of the test
Modified file 'storage/falcon/IndexWalker.cpp'
----------------------------------------------
Initialize lastRecordNumber to a negative value
added:
mysql-test/suite/falcon/r/falcon_bug_43452.result
mysql-test/suite/falcon/t/falcon_bug_43452.test
modified:
storage/falcon/IndexWalker.cpp
=== added file 'mysql-test/suite/falcon/r/falcon_bug_43452.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_43452.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_43452.result 2009-03-06 13:51:05 +0000
@@ -0,0 +1,30 @@
+*** Bug #43452 ***
+SET @@storage_engine = 'Falcon';
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (int_key INTEGER, KEY (int_key));
+INSERT INTO t1 VALUES (1), (8);
+UPDATE t1 SET int_key = 3;
+SELECT * FROM t1 WHERE int_key < 8;
+int_key
+3
+3
+SELECT * FROM t1 WHERE int_key < 8 ORDER BY int_key LIMIT 4;
+int_key
+3
+3
+DROP TABLE t1;
+CREATE TABLE t1 (int_key INTEGER, KEY (int_key)) ENGINE=falcon;
+INSERT INTO t1 VALUES (8), (1);
+UPDATE t1 SET int_key = 3;
+SELECT * FROM t1 WHERE int_key < 8;
+int_key
+3
+3
+SELECT * FROM t1 WHERE int_key < 8 ORDER BY int_key LIMIT 4;
+int_key
+3
+3
+SELECT count(*) FROM t1;
+count(*)
+2
+DROP TABLE t1;
=== added file 'mysql-test/suite/falcon/t/falcon_bug_43452.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_43452.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_43452.test 2009-03-06 13:51:05 +0000
@@ -0,0 +1,44 @@
+--source include/have_falcon.inc
+
+#
+# Bug #43452: Wrong number of rows returned when using LIMIT
+#
+--echo *** Bug #43452 ***
+
+# ----------------------------------------------------- #
+# --- Initialisation --- #
+# ----------------------------------------------------- #
+let $engine = 'Falcon';
+eval SET @@storage_engine = $engine;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# ----------------------------------------------------- #
+# --- Test --- #
+# ----------------------------------------------------- #
+
+CREATE TABLE t1 (int_key INTEGER, KEY (int_key));
+INSERT INTO t1 VALUES (1), (8);
+UPDATE t1 SET int_key = 3;
+SELECT * FROM t1 WHERE int_key < 8;
+SELECT * FROM t1 WHERE int_key < 8 ORDER BY int_key LIMIT 4;
+DROP TABLE t1;
+
+# Testing the same, but with the records inserted in the opposite order
+CREATE TABLE t1 (int_key INTEGER, KEY (int_key)) ENGINE=falcon;
+INSERT INTO t1 VALUES (8), (1);
+UPDATE t1 SET int_key = 3;
+SELECT * FROM t1 WHERE int_key < 8;
+SELECT * FROM t1 WHERE int_key < 8 ORDER BY int_key LIMIT 4;
+
+# ----------------------------------------------------- #
+# --- Check --- #
+# ----------------------------------------------------- #
+SELECT count(*) FROM t1;
+
+# ----------------------------------------------------- #
+# --- Final cleanup --- #
+# ----------------------------------------------------- #
+DROP TABLE t1;
=== modified file 'storage/falcon/IndexWalker.cpp'
--- a/storage/falcon/IndexWalker.cpp 2009-02-26 20:04:31 +0000
+++ b/storage/falcon/IndexWalker.cpp 2009-03-06 13:51:05 +0000
@@ -24,7 +24,8 @@
parent->lower = newChild; \
else \
parent->higher = newChild;
-
+
+#define INITIAL_LAST_RECORD_NUMBER -3
IndexWalker::IndexWalker(Index *idx, Transaction *trans, int flags)
{
@@ -39,7 +40,7 @@ IndexWalker::IndexWalker(Index *idx, Tra
balance = 0;
higher = NULL;
lower = NULL;
- lastRecordNumber = 0;
+ lastRecordNumber = INITIAL_LAST_RECORD_NUMBER;
firstRecord = true;
}
Attachment: [text/bzr-bundle] bzr/lars-erik.bjork@sun.com-20090306135105-1b89sdkazcyxvnao.bundle
| Thread |
|---|
| • bzr commit into mysql-6.0-falcon-team branch (lars-erik.bjork:3054) Bug#43452 | lars-erik.bjork | 6 Mar |