List:Commits« Previous MessageNext Message »
From:lars-erik.bjork Date:March 7 2009 7:52am
Subject:bzr push into mysql-6.0-falcon-team branch (lars-erik.bjork:3054 to 3055)
Bug#43452
View as plain text  
 3055 lars-erik.bjork@stripped	2009-03-07
      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
 3054 Kevin Lewis	2009-03-07
      Code cleanup

    modified:
      storage/falcon/Debug.cpp
      storage/falcon/MemControl.cpp
      storage/falcon/Record.cpp
      storage/falcon/SQLError.cpp
      storage/falcon/SavePoint.cpp
      storage/falcon/Schedule.cpp
      storage/falcon/Table.cpp
      storage/falcon/Transaction.h
=== 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-07 07:51:29 +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));
+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-07 07:51:29 +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));
+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-07 07:51:29 +0000
@@ -24,7 +24,11 @@
 		parent->lower = newChild;	 \
 	else							\
 		parent->higher = newChild;
-		
+
+// Using a negative record number, that is not
+// END_BUCKET (-1) or END_LEVEL (-2) which are defined
+// in Page.h
+static const int32 INITIAL_LAST_RECORD_NUMBER = -3;		
 
 IndexWalker::IndexWalker(Index *idx, Transaction *trans, int flags)
 {
@@ -39,7 +43,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-20090307075129-kfuj2ueaxm24qrhm.bundle
Thread
bzr push into mysql-6.0-falcon-team branch (lars-erik.bjork:3054 to 3055)Bug#43452lars-erik.bjork7 Mar