#At file:///home/lb200670/mysql/clean/ based on revid:kevin.lewis@stripped
2712 lars-erik.bjork@stripped 2009-05-25
This is the second of two patches for bug#43630
A SELECT using ORDER BY and LIMIT sometimes returns no rows
When we look at the first index entry of a page, the following piece of code is executed:
for (;; first = true)
{
if (first)
{
first = false;
recordNumber = node.getNumber();
if (recordNumber >= 0)
{
return recordNumber;
}
We return the recordNumber without setting up indexKey to reflect the first index entry on
the page. This will only work in two scenarioes:
1: If the key value of the END_BUCKET node on the previous page is the same as the key
value of the first index node on the current page
2: If this is the first page we look at during the search
With a lot of UPDATE/DELETE statements, the prerequisites for scenario 1 to be correct,
may easily be broken, and we will get wrong results.
The fix is to call node.expandKey(&indexKey) if this is the first node on the page. This
is however not necessary if it is the first page we look at during the search, as this has
already been done in IndexRootPage::positionIndex
modified:
storage/falcon/WalkIndex.cpp
storage/falcon/WalkIndex.h
per-file messages:
storage/falcon/WalkIndex.cpp
Added a call to node.expandKey(&indexKey) if this is the first valid node on a page that is not the first page of the search
storage/falcon/WalkIndex.h
Added a bool saying if this is the first page in the search. Initialized to 'true' in the WalkIndex constructor
=== modified file 'storage/falcon/WalkIndex.cpp'
--- a/storage/falcon/WalkIndex.cpp 2009-05-09 11:25:17 +0000
+++ b/storage/falcon/WalkIndex.cpp 2009-05-25 11:10:37 +0000
@@ -43,6 +43,7 @@ WalkIndex::WalkIndex(Index *index, Trans
nodes = new UCHAR[transaction->database->dbb->pageSize];
key = indexKey.key;
+ firstPageInSearch = true;
}
WalkIndex::~WalkIndex(void)
@@ -89,6 +90,25 @@ int32 WalkIndex::getNextNode(void)
if (recordNumber >= 0)
{
+
+ if (firstPageInSearch)
+ {
+
+ // indexKey already reflects the first index
+ // entry on the page
+
+ firstPageInSearch = false;
+ }
+ else
+ {
+
+ // We cannot assume that the key is the same
+ // as the END_BUCKET key of the previous page,
+ // as these values may diverge
+
+ node.expandKey(&indexKey);
+ }
+
return recordNumber;
}
else if (recordNumber == END_BUCKET)
=== modified file 'storage/falcon/WalkIndex.h'
--- a/storage/falcon/WalkIndex.h 2008-05-07 22:37:18 +0000
+++ b/storage/falcon/WalkIndex.h 2009-05-25 11:10:37 +0000
@@ -41,6 +41,7 @@ public:
IndexKey indexKey;
Btn *endNodes;
int32 nextPage;
+ bool firstPageInSearch;
};
#endif